To jeden z możliwych sposobów, w jaki wychodzę:
struct RetrieveKey
{
template <typename T>
typename T::first_type operator()(T keyValuePair) const
{
return keyValuePair.first;
}
};
map<int, int> m;
vector<int> keys;
// Retrieve all keys
transform(m.begin(), m.end(), back_inserter(keys), RetrieveKey());
// Dump all keys
copy(keys.begin(), keys.end(), ostream_iterator<int>(cout, "\n"));
Oczywiście możemy również pobrać wszystkie wartości z mapy, definiując kolejny funktor RetrieveValues .
Czy jest jakiś inny sposób na osiągnięcie tego łatwo? (Zawsze zastanawiam się, dlaczego std :: map nie zawiera dla nas funkcji członka).
c++
dictionary
stl
stdmap
piekarnik
źródło
źródło
keys.reserve(m.size());
.Odpowiedzi:
Chociaż twoje rozwiązanie powinno działać, może być trudne do odczytania, w zależności od poziomu umiejętności innych programistów. Dodatkowo przenosi funkcjonalność z dala od strony połączeń. Co może utrudnić konserwację.
Nie jestem pewien, czy twoim celem jest wprowadzenie kluczy do wektora lub wydrukowanie ich, aby zrobić to, więc robię oba. Możesz spróbować czegoś takiego:
Lub nawet prościej, jeśli używasz wzmocnienia:
Osobiście podoba mi się wersja BOOST_FOREACH, ponieważ jest mniej pisania i jest bardzo wyraźna na temat tego, co robi.
źródło
BOOST_FOREACH
? Proponowany tutaj kod jest całkowicie niepoprawnyv.reserve(m.size())
aby uniknąć zmiany rozmiaru wektora podczas przesyłania.źródło
it = ...begin(); it != ...end
. Najładniejszy byłby oczywiście std :: map posiadający metodę keys () zwracającą ten wektor ...answered Mar 13 '12 at 22:33
kilka miesięcy po tym, jak C ++ 11 stało się C ++.for(auto const & imap : mapints)
.Jest to adapter zakres impuls do tego celu:
Istnieje podobny adapter zakresu map_values do wyodrębniania wartości.
źródło
boost::adaptors
nie jest dostępny do momentu wzmocnienia 1.43. Obecne stabilne wydanie Debiana (Squeeze) oferuje tylko Boost 1.42boost/range/adaptor/map.hpp
C ++ 0x dał nam kolejne doskonałe rozwiązanie:
źródło
Odpowiedź DanDana przy użyciu C ++ 11 brzmi:
i przy użyciu C ++ 14 (jak wskazano przez @ ivan.ukr) może zastąpić
decltype(map_in)::value_type
zauto
.źródło
keys.reserve(map_in.size());
do wydajności.SGI STL ma rozszerzenie o nazwie
select1st
. Szkoda, że nie ma go w standardowym STL!źródło
Twoje rozwiązanie jest w porządku, ale możesz to zrobić za pomocą iteratora:
źródło
Oparty na rozwiązaniu @ rusty-parks, ale w c ++ 17:
źródło
std::ignore
można było tego używać w powiązaniach strukturalnych. Otrzymuję błąd kompilacji. Wystarczy użyć zwykłej zmiennej, np. Poignored
prostu się nie przyzwyczai.std::ignore
jest przeznaczony do stosowania z,std::tie
ale nie z wiązaniami strukturalnymi. Zaktualizowałem swój kod.Myślę, że BOOST_FOREACH przedstawiony powyżej jest ładny i czysty, jednak istnieje również inna opcja korzystania z BOOST.
Osobiście nie sądzę, aby to podejście było tak czyste jak podejście BOOST_FOREACH w tym przypadku, ale boost :: lambda może być naprawdę czyste w innych przypadkach.
źródło
Ponadto, jeśli masz Boost, użyj transform_iterator, aby uniknąć tworzenia tymczasowej kopii kluczy.
źródło
Trochę c ++ 11 wziąć:
źródło
Możesz użyć uniwersalnego boost :: transform_iterator. Transform_iterator pozwala na przekształcenie iterowanych wartości, na przykład w naszym przypadku, gdy chcesz zajmować się tylko kluczami, a nie wartościami. Zobacz http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/transform_iterator.html#example
źródło
Oto ładny szablon funkcji wykorzystujący magię C ++ 11, działający zarówno dla std :: map, std :: unordered_map:
Sprawdź to tutaj: http://ideone.com/lYBzpL
źródło
Najlepszym rozwiązaniem STL innym niż sgi, nie doładowującym jest rozszerzenie map :: iterator w następujący sposób:
a następnie użyj ich w następujący sposób:
źródło
Z przykładem mapy atomowej
źródło
Nieco podobny do jednego z przykładów tutaj, uproszczony z
std::map
perspektywy użytkowania.Użyj w ten sposób:
źródło
map.size()
pomocą rozmiaru oznacza dwukrotność zwrotu rozmiaru wektora. Proszę naprawić, aby zaoszczędzić komuś ból głowy :(Ponieważ nie może tego zrobić lepiej niż ty. Jeśli implementacja metody nie będzie lepsza niż implementacja wolnej funkcji, to na ogół nie powinieneś pisać metody; powinieneś napisać darmową funkcję.
Nie jest też od razu jasne, dlaczego jest to przydatne.
źródło
empty()
ponieważ można go zaimplementować jakosize() == 0
.std::map<T,U>
jak kontener par. W Pythonie adict
działa jak klucze po iteracji, ale pozwala powiedzieć,d.items()
aby uzyskać zachowanie w C ++. Python zapewnia równieżd.values()
.std::map<T,U>
z pewnością może zapewnić metodękeys()
ivalues()
, która zwraca obiekt, który mabegin()
iend()
zapewnia iteratory nad kluczami i wartościami.