How do I merge two maps in STL and apply a function for conflicts?

  • A+
Category:Languages

I have read the Merge two STL maps question, and though it's close I was looking for functionality like the one described here.

In short, I would like to have merge two std::map instances (having thee same key and value type) into one, with the caveat that I would like to add the values together if the object exists in both maps.

Is there an existing boost, range-v3, or std function that can do this? And if not, what would be the best way to achieve it?

Example code:

double mergePredicate(double lhs, double rhs) {     return lhs + rhs; }  int main() {     std::map<int, double> mapA = { {0, 1.0}, {1, 2.0} };     std::map<int, double> mapB = { {1, 1.5}, {2, 2.5} };      // Merge maps in some way...     merge(mapA, mapB, mergePredicate);      // result: mapA == { {0, 1.0}, {1, 3.5}, {2, 2.5} }     for (const auto& p : mapA) {         std::cout << p.first << " " << p.second << std::endl;     } } 

 


I don't know of any existing function for that, but you can roll your own from something similar to std::merge implementation to have linear complexity:

template<class Map, class Merger> void merge(Map& dest, const Map& source, Merger merger) {     auto it1 = dest.begin();     auto it2 = source.begin();     auto&& comp = dest.value_comp();      for (; it1 != dest.end() && it2 != source.end(); ) {         if (comp(*it1, *it2)) {             ++it1;         } else if (comp(*it2, *it1)) {             dest.insert(it1, *it2); // with hint to have correct complexity             ++it2;         } else { // equivalent             it1->second = merger(it1->second, it2->second);             ++it1;             ++it2;         }     }     dest.insert(it2, source.end()); } 

Demo

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: