Comment faire pour récupérer toutes les clés (ou des valeurs) d'un std::map et les mettre dans un vecteur?
C'est l'une des voies possibles et je sors:
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"));
Bien sûr, nous pouvons également récupérer toutes les valeurs de la carte par la définition d'un autre foncteur RetrieveValues.
Est-il un autre moyen de réaliser cela facilement? (Je me suis toujours demandé pourquoi std::map ne comprend pas une fonction membre pour nous de le faire.)
- votre solution est la meilleure...
- La seule chose que je voudrais ajouter t c'est
keys.reserve(m.size());
.
Vous devez vous connecter pour publier un commentaire.
Alors que votre solution devrait fonctionner, il peut être difficile à lire selon le niveau de compétence de vos collègues programmeurs. En outre, il se déplace de la fonctionnalité loin du site d'appel. Qui peut faire de l'entretien un peu plus difficile.
Je ne suis pas sûr si votre objectif est de récupérer les clés dans un vecteur ou de les imprimer à cout donc, je suis en train de faire à la fois. Vous pouvez essayer quelque chose comme ceci:
Ou encore plus simple, si vous utilisez le Boost:
Personnellement, j'aime le BOOST_FOREACH version car il y a moins de taper et il est très explicite sur ce qu'il fait.
BOOST_FOREACH
? Le code vous proposons ici, c'est totalement fauxv.reserve(m.size())
pour éviter d'avoir le vecteur redimensionner pendant le transfert.it = ...begin(); it != ...end
. Plus belle serait la std::map de disposer d'une méthode keys() renvoi de ce vecteur...answered Mar 13 '12 at 22:33
, qui est de plusieurs mois après C++11 est devenu C++.for(auto const & imap : mapints)
.for (auto&& imap : mapints)
. Voir edmundv.home.xs4all.nl/blog/2014/01/28/...vints.reserve( mapints.size() );
avant la boucle.Il y a un stimuler la gamme d'adaptateur à cet effet:
Il est similaire map_values gamme d'adaptateur pour extraire les valeurs.
boost::adaptors
n'est pas disponible jusqu'à ce Boost 1.43. L'actuelle version stable de Debian (Squeeze) propose uniquement des Boost de 1,42boost/range/adaptor/map.hpp
C++0x nous a donné une excellente solution:
@DanDan réponse, à l'aide de C++11 est:
et à l'aide de C++14 (comme indiqué par @ivan.ukr), nous pouvons remplacer
decltype(map_in)::value_type
avecauto
.keys.reserve(map_in.size());
pour plus d'efficacité.La SGI STL a une extension appelée
select1st
. Dommage qu'il n'est pas dans la norme de la STL!Je pense que le BOOST_FOREACH présenté ci-dessus est agréable et propre, cependant, il ya une autre option à l'aide de STIMULER ainsi.
Personnellement, je ne pense pas que cette approche est aussi propre que le BOOST_FOREACH approche dans ce cas, mais boost::lambda peut être vraiment propre dans les autres cas.
Votre solution est bien, mais vous pouvez utiliser un itérateur pour le faire:
Aussi, si vous avez le coup de pouce, l'utilisation transform_iterator pour éviter de faire une copie temporaire des clés.
Vous pouvez utiliser le polyvalent boost::transform_iterator. Le transform_iterator permet de transformer l'itéré valeurs, par exemple dans notre cas, lorsque vous voulez traiter uniquement avec les touches, pas de les valeurs. Voir http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/transform_iterator.html#example
Peu de c++11:
Le meilleur non-sgi, non-boost, STL solution consiste à étendre la carte::iterator comme suit:
et ensuite de les utiliser comme:
Voici un joli modèle de fonction à l'aide de C++11 de la magie, de travail pour les std::map, std::unordered_map:
Découvrez-le ici: http://ideone.com/lYBzpL
Basé sur @rusty-parcs solution, mais en c++17:
Un peu similaire à l'un des exemples ici, simplifié à partir de
std::map
l'utilisation de la perspective.Utiliser comme ceci:
map.size()
à-dire le double de la taille de vecteur de retour. Veuillez les corriger, pour sauver quelqu'un d'autre le mal de tête 🙁Car il ne peut pas faire mieux que ce que vous pouvez faire. Si une méthode de la mise en œuvre sera pas supérieure à un libre de la fonction de la mise en œuvre puis en général, vous ne devriez pas écrire une méthode; vous devez écrire une fonction libre.
Il n'est également pas immédiatement clair pourquoi il est utile de toute façon.
empty()
car il peut être mis en œuvre commesize() == 0
.std::map<T,U>
comme un conteneur de paires. En Python, undict
actes comme de ses clefs quand itéré, mais permet de dired.items()
pour obtenir le C++ comportement. Python fournit égalementd.values()
.std::map<T,U>
pourrait certainement fournir unekeys()
etvalues()
méthode qui retourne un objet qui abegin()
etend()
qui fournissent des itérateurs sur les clés et les valeurs.