web-dev-qa-db-fra.com

Copier std :: map dans std :: vecteur de paires

J'essaie de copier une carte dans un vecteur de paire, donc je peux ensuite trier le vecteur par le membre de données second des paires. J'ai résolu cela en faisant comme ceci:

void mappedWordsListSorter(){
  for (auto itr = mappedWordsList.begin(); itr != mappedWordsList.end(); ++itr){
    vectorWordsList.Push_back(*itr);
  }
  sort(vectorWordsList.begin(), vectorWordsList.end(), [=](pair<string, int>& a, pair<string, int>& b){return a.second > b.second;});
}

J'ai besoin de trouver un moyen de le faire sans utiliser de boucle brute, en utilisant plutôt la bibliothèque standard. J'ai rencontré de nombreux exemples pour ce faire en transférant uniquement les clés ou les valeurs de la carte. Je dois copier dans un vecteur de pairs<string, int>. Quelle est la meilleure façon de procéder?

17
Victor

Utilisez simplement std::vector's assign fonction membre.

//no need to call reserve, bidirectional iterators or better will compute the size and reserve internally.
vectorWordsList.assign(mappedWordsList.begin(), mappedWordsList.end());

Si vous avez des valeurs existantes dans le vecteur que vous ne voulez pas écraser, utilisez plutôt insert comme

vectorWordsList.reserve(vectorWordsList.size() + mappedWordsList.size()); // make sure we only have a single memory allocation
vectorWordsList.insert(vectorWordsList.end(), mappedWordsList.begin(), mappedWordsList.end());
22
NathanOliver

Vous pouvez utiliser std::copy et std::back_inserter:

std::copy(mappedWordsList.begin(), 
          mappedWordsList.end(), 
          std::back_inserter(vectorWordsList));

Honnêtement, je pense qu'une boucle gamme -for est plus claire:

for(const auto& kv : mappedWordsList) 
     vectorWordsList.emplace_back(kv);

Quoi qu'il en soit, vous pouvez utiliser std::vector::reserve pour préallouer de la mémoire sur votre cible vector, en évitant les réallocations inutiles.

7
Vittorio Romeo

Il convient de noter que si vous êtes création d'un vecteur à cet effet, vous pouvez utiliser directement le constructeur du vecteur:

std::vector<std::pair<FirstType,SecondType>> vectorWordsList( mappedWordsList.begin(), mappedWordsList.end() );

En C++ 17, vous pouvez également omettre les arguments de modèle du vecteur pour que le compilateur les déduise:

std::vector vectorWordsList( mappedWordsList.begin(), mappedWordsList.end() );
7
Drew Dormann