Как извлечь все ключи (или значения) из std :: map и поместить их в вектор?

Это один из возможных способов:

struct RetrieveKey { template  typename T::first_type operator()(T keyValuePair) const { return keyValuePair.first; } }; map m; vector keys; // Retrieve all keys transform(m.begin(), m.end(), back_inserter(keys), RetrieveKey()); // Dump all keys copy(keys.begin(), keys.end(), ostream_iterator(cout, "\n")); 

Конечно, мы также можем извлечь все значения из карты, определив еще один функтор RetrieveValues .

Есть ли другой способ добиться этого легко? (Мне всегда интересно, почему std :: map не включает в себя функцию-член для нас.)

Хотя ваше решение должно работать, его может быть трудно читать в зависимости от уровня навыков ваших коллег-программистов. Кроме того, он перемещает функциональность в стороне от сайта вызова. Что может сделать обслуживание немного сложнее.

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

 map m; vector v; for(map::iterator it = m.begin(); it != m.end(); ++it) { v.push_back(it->first); cout << it->first << "\n"; } 

Или даже проще, если вы используете Boost:

 map m; pair me; // what a map is made of vector v; BOOST_FOREACH(me, m) { v.push_back(me.first); cout << me.first << "\n"; } 

Лично мне нравится версия BOOST_FOREACH, потому что набирается меньше текста, и она очень ясна в том, что она делает.

 //c++0x too std::map mapints; std::vector vints; vints.reserve(mapints.size()); for(auto const& imap: mapints) vints.push_back(imap.first); 

Для этой цели имеется адаптер диапазона ускорения :

 vector keys; // Retrieve all keys boost::copy(m | boost::adaptors::map_keys, std::back_inserter(keys)); 

Существует аналогичный адаптер диапазона map_values ​​для извлечения значений.

C ++ 0x дал нам еще одно превосходное решение:

 std::vector keys; std::transform( m_Inputs.begin(), m_Inputs.end(), std::back_inserter(keys), [](const std::map::value_type &pair){return pair.first;}); 

SGI STL имеет расширение, называемое select1st . Жаль, что это не стандартный STL!

Я думаю, что представленный выше BOOST_FOREACH хорош и чист, однако есть и другой вариант, использующий BOOST.

 #include  #include  std::map m; std::vector keys; using namespace boost::lambda; transform( m.begin(), m.end(), back_inserter(keys), bind( &std::map::value_type::first, _1 ) ); copy( keys.begin(), keys.end(), std::ostream_iterator(std::cout, "\n") ); 

Лично я не думаю, что этот подход так же чист, как подход BOOST_FOREACH в этом случае, но boost :: lambda может быть действительно чистым в других случаях.

@ Ответ DanDan, использующий C ++ 11:

 using namespace std; vector keys; transform(begin(map_in), end(map_in), back_inserter(keys), [](decltype(map_in)::value_type const& pair) { return pair.first; }); 

и используя C ++ 14 (как отмечено @ ivan.ukr), мы можем заменить decltype(map_in)::value_type на auto .

Ваше решение в порядке, но вы можете использовать iterator для этого:

 std::map m; m.insert(std::pair(3, 4)); m.insert(std::pair(5, 6)); for(std::map::const_iterator it = m.begin(); it != m.end(); it++) { int key = it->first; int value = it->second; //Do something } 

Кроме того, если у вас есть Boost, используйте transform_iterator, чтобы избежать временной копии ключей.

Вы можете использовать универсальный boost :: transform_iterator. Преобразователь transform_iterator позволяет вам преобразовывать итерированные значения, например, в нашем случае, когда вы хотите иметь дело только с ключами, а не с значениями. См. http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/transform_iterator.html#example

Лучшим решением non-sgi, non-boost STL является расширение map :: iterator:

 template class key_iterator : public map_type::iterator { public: typedef typename map_type::iterator map_iterator; typedef typename map_iterator::value_type::first_type key_type; key_iterator(const map_iterator& other) : map_type::iterator(other) {} ; key_type& operator *() { return map_type::iterator::operator*().first; } }; // helpers to create iterators easier: template key_iterator key_begin(map_type& m) { return key_iterator(m.begin()); } template key_iterator key_end(map_type& m) { return key_iterator(m.end()); } 

и затем используйте их так:

  map test; test["one"] = 1; test["two"] = 2; vector keys; // // method one // key_iterator > kb(test.begin()); // key_iterator > ke(test.end()); // keys.insert(keys.begin(), kb, ke); // // method two // keys.insert(keys.begin(), // key_iterator >(test.begin()), // key_iterator >(test.end())); // method three (with helpers) keys.insert(keys.begin(), key_begin(test), key_end(test)); string one = keys[0]; 

Бит c ++ 11:

 std::map items; std::vector itemKeys; for (auto & kvp : items) { itemKeys.emplace_back(kvp.first); std::cout << kvp.first << std::endl; } 

Вот хороший шаблон функции с использованием C ++ 11 magic, работающий как для std :: map, std :: unordered_map:

 template 

Посмотрите здесь: http://ideone.com/lYBzpL

(Мне всегда интересно, почему std :: map не включает в себя функцию-член для нас.)

Потому что он не может сделать это лучше, чем вы можете это сделать. Если реализация метода не будет превосходить реализацию свободной функции, тогда вообще вы не должны писать метод; вы должны написать бесплатную функцию.

Также не сразу понятно, почему это так полезно.

  • Hashtable с многомерным ключом в C #
  • Как преобразовать строку JSON в словарь?
  • C # JSON Сериализация словаря в {key: value, ...} вместо {key: key, value: value, ...}
  • Как определить хеш-таблицы в Bash?
  • Сопоставление объекта со словарем и наоборот
  • .NET HashTable Vs Dictionary - Может ли словарь быть таким же быстрым?
  • Доступ к определенному полю в произвольно вложенных данных JSON
  • Использование поля объекта в качестве общего ключа словаря
  • Словарь Swift - ключ к значению
  • Как удалить ключ из HashMap, итерации по нему?
  • Что более эффективно: Словарь TryGetValue или ContainsKey + Item?
  • Interesting Posts

    Есть ли готовая готовая к запуску очередь или хеш-реализация в C ++

    Перемешать массив в C

    Префиксы XML-сериализации и пространства имен

    Как я запускаю приложение gnome и позволяю ему работать через SSH даже после закрытия SSH?

    Каков наилучший формат файла / скорость передачи битов для копирования треков с компакт-диска в iTunes?

    Есть ли разница между foo (void) и foo () в C ++ или C?

    Как найти, что ScrollViewer прокручивается до конца в WPF?

    Объединить атрибуты CSS и псевдоэлементы?

    Как установить параметры JVM для тестов Junit Unit?

    Имеет ли XAML условную директиву компилятора для режима отладки?

    Не удается запустить отладку на веб-сервере. Не удалось запустить отладку ASP.NET VS 2010, II7, Win 7 x64

    Android: Как получить текущее смещение X для RecyclerView?

    Как предотвратить захват экрана в Android

    Как преобразовать String в Date без знания формата?

    Создание пользовательского UIKeyBoard для iPhone

    Давайте будем гением компьютера.