Скопируйте std :: map в std :: vector пар

Я пытаюсь скопировать карту в вектор пары, чтобы потом можно было отсортировать вектор по second элементу данных пар. Я решил это сделать так:

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;});
}

Мне нужно найти способ сделать это без использования сырого цикла, используя вместо этого стандартную библиотеку. Я сталкивался с множеством примеров, делающих это, только передавая либо ключи, либо значения карты. Мне нужно скопировать в вектор pairs<string, int>. Каков наилучший способ сделать это?

Ответ 1

Просто используйте std::vector assign функцию-член.

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

Если у вас есть значения в векторе, которые вы не хотите перезаписывать, используйте вместо этого команду insert

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

Ответ 2

Вы можете использовать std::copy и std::back_inserter:

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

Честно говоря, я думаю, что цикл range- for более понятен:

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

В любом случае, вы можете использовать std::vector::reserve для предварительного выделения памяти на целевом vector, избегая ненужных перераспределений.

Ответ 3

Стоит отметить, что если вы создаете вектор для этой цели, вы можете использовать конструктор вектора напрямую:

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

В С++ 17 вы также можете опустить аргументы векторного шаблона, чтобы компилятор выводил их:

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