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

Используя STL в С++, как мне применить функцию к каждому значению в std::map, чтобы получить std::string (печатное представление значения) и собрать std::string(s) в коллекцию, которая отсортирована по ключу с плавающей запятой, который приходит из другой функции, примененной к каждому соответствующему значению на карте?

Другими словами, я хочу перебрать пары ключ-значение на карте и создать новый набор пар ключ-значение, где новый ключ и значение являются функцией старого значения.

double getNewKey(origValue value);
std::string getNewValue(origValue value);
// Or is it better to map both at once in a pair?
std::pair<double, std::string> getNewPair(origValue value);

std::map<origKey, origValue> origMap;

// Perform some transformation on each value of origMap to get a new map:
std::map<double, std::string> transformedMap =
  /* What goes here to use getNewKey() and getNewValue() or use getNewPair()? */
  ;

Но, пожалуйста, без использования С++ 11.


person WilliamKF    schedule 03.08.2012    source источник
comment
Посмотрите на std::transform и std::back_inserter   -  person David Rodríguez - dribeas    schedule 03.08.2012
comment
хотя я думаю, что вам нужно std::inserter, если вывод также является картой   -  person Useless    schedule 03.08.2012


Ответы (2)


std::transform это то, что вам нужно:

#include <map>
#include <algorithm>
#include <iterator>
#include <iostream>

// using a few C++11 features to make life easier
int main(){
  std::map<int, int> src, dst; // example KV pair
  for(unsigned i=0; i < 10; ++i)
    src[i] = i;
  typedef std::map<int, int>::value_type kv_pair;
  std::transform(src.begin(), src.end(), std::inserter(dst, dst.begin()),
      [](kv_pair const& p){
        return kv_pair(p.first, p.second * 2);
      });
  for(auto& p : dst)
    std::cout << p.first << " : " << p.second << "\n";
}

Живой пример.

person Xeo    schedule 03.08.2012
comment
Как насчет без функций С++ 11? - person WilliamKF; 03.08.2012
comment
@WilliamKF: вам нужно будет изменить лямбду на функцию/функтор. - person David Rodríguez - dribeas; 03.08.2012
comment
@WilliamKF: Как говорит Дэвид, замените лямбда функцией/функтором, и, очевидно, вы не сможете использовать цикл с ранжированием. - person Xeo; 03.08.2012

[Отказ от ответственности, непроверено]:

std::pair<NewKey,NewValue> transform( std::pair<const OldKey,OldValue> const & x ) {
   return std::make_pair( getNewKey(x.first), getNewValue(x.second) );
}
...
std::transfom( m.begin(), m.end(),
               std::inserter( newmap, m.end() ),
               transform );
person David Rodríguez - dribeas    schedule 03.08.2012