Dies ist einer der möglichen Wege, wie ich herauskomme:
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"));
Natürlich können wir auch alle Werte von der Karte abrufen, indem wir einen anderen Funktor RetrieveValues definieren .
Gibt es eine andere Möglichkeit, dies einfach zu erreichen? (Ich frage mich immer, warum std :: map keine Mitgliedsfunktion enthält, damit wir dies tun können.)
c++
dictionary
stl
stdmap
Owen
quelle
quelle
keys.reserve(m.size());
.Antworten:
Während Ihre Lösung funktionieren sollte, kann es je nach Kenntnisstand Ihrer Programmierkollegen schwierig sein, sie zu lesen. Darüber hinaus werden Funktionen von der Anrufstelle entfernt. Das kann die Wartung etwas erschweren.
Ich bin mir nicht sicher, ob Ihr Ziel darin besteht, die Schlüssel in einen Vektor zu bringen oder sie zu drucken, damit ich beides mache. Sie können so etwas versuchen:
Oder noch einfacher, wenn Sie Boost verwenden:
Persönlich mag ich die BOOST_FOREACH-Version, weil weniger getippt wird und sehr explizit ist, was sie tut.
quelle
BOOST_FOREACH
? Der Code, den Sie hier vorschlagen, ist völlig falschv.reserve(m.size())
, um zu vermeiden, dass die Größe des Vektors während der Übertragung geändert wird.quelle
it = ...begin(); it != ...end
. Am schönsten wäre natürlich std :: map mit einem Methodenschlüssel (), der diesen Vektoranswered Mar 13 '12 at 22:33
, einige Monate nachdem C ++ 11 zu C ++ wurde.for(auto const & imap : mapints)
.Zu diesem Zweck gibt es einen Boost-Range-Adapter :
Es gibt einen ähnlichen Bereichsadapter für map_values zum Extrahieren der Werte.
quelle
boost::adaptors
es nicht verfügbar zu sein, bis Boost 1.43. Die aktuelle stabile Version von Debian (Squeeze) bietet nur Boost 1.42boost/range/adaptor/map.hpp
C ++ 0x hat uns eine weitere, hervorragende Lösung gegeben:
quelle
Die Antwort von @ DanDan unter Verwendung von C ++ 11 lautet:
und unter Verwendung von C ++ 14 (wie bereits von @ ivan.ukr) können wir ersetzen
decltype(map_in)::value_type
mitauto
.quelle
keys.reserve(map_in.size());
für die Effizienz hinzufügen .Die SGI STL hat eine Nebenstelle namens
select1st
. Schade, dass es nicht in Standard-STL ist!quelle
Ihre Lösung ist in Ordnung, aber Sie können einen Iterator verwenden, um dies zu tun:
quelle
Basierend auf der @ Rusty-Parks-Lösung, jedoch in c ++ 17:
quelle
std::ignore
man auf diese Weise in strukturierten Bindungen verwendet werden kann. Ich erhalte einen Kompilierungsfehler. Es sollte ausreichen, nur eine reguläre Variable zu verwenden, z. B.ignored
die einfach nicht verwendet wird.std::ignore
ist zur Verwendung mit,std::tie
aber nicht mit strukturellen Bindungen vorgesehen. Ich habe meinen Code aktualisiert.Ich denke, der oben vorgestellte BOOST_FOREACH ist schön und sauber, aber es gibt auch eine andere Option, die BOOST verwendet.
Persönlich denke ich nicht, dass dieser Ansatz in diesem Fall so sauber ist wie der BOOST_FOREACH-Ansatz, aber boost :: lambda kann in anderen Fällen wirklich sauber sein.
quelle
Wenn Sie über Boost verfügen, verwenden Sie transform_iterator, um zu vermeiden, dass eine temporäre Kopie der Schlüssel erstellt wird.
quelle
Ein bisschen wie ein C ++ 11-Take:
quelle
Sie können den vielseitigen boost :: transform_iterator verwenden. Mit dem transform_iterator können Sie die iterierten Werte transformieren, beispielsweise in unserem Fall, wenn Sie nur die Schlüssel und nicht die Werte behandeln möchten. Siehe http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/transform_iterator.html#example
quelle
Hier ist eine nette Funktionsvorlage mit C ++ 11-Magie, die sowohl für std :: map als auch für std :: unordered_map funktioniert:
Überprüfen Sie es hier: http://ideone.com/lYBzpL
quelle
Die beste STL-Lösung ohne SGI und ohne Boost besteht darin, map :: iterator wie folgt zu erweitern:
und dann benutze sie so:
quelle
Mit Atomkartenbeispiel
quelle
Etwas ähnlich wie eines der hier gezeigten Beispiele, vereinfacht aus
std::map
Sicht der Nutzung.Verwenden Sie wie folgt:
quelle
map.size()
bedeutet die doppelte Rückgabe der Vektorgröße. BitteWeil es nicht besser geht als Sie. Wenn die Implementierung einer Methode der Implementierung einer freien Funktion nicht überlegen ist, sollten Sie im Allgemeinen keine Methode schreiben. Sie sollten eine freie Funktion schreiben.
Es ist auch nicht sofort klar, warum es sowieso nützlich ist.
quelle
empty()
weil es als implementiert werden kannsize() == 0
.std::map<T,U>
als Container von Paaren behandelt. In Pythondict
verhält sich a wie seine Schlüssel, wenn es wiederholt wird, aber Sie können sagend.items()
, dass Sie das C ++ - Verhalten erhalten möchten. Python bietet auchd.values()
.std::map<T,U>
sicherlich könnte liefernkeys()
undvalues()
Methode , die ein Objekt zurück, das hatbegin()
undend()
die Iteratoren über die Schlüssel und Werte liefern.