Question

I'm looking for a way to copy values from one map into another, similar to this question, but I don't want conflicting values to be overwritten by the second map, I want the original values to remain untouched.

For example, if I had two maps {a: 1, b: 2}, and I copied {b: 3, c: 4} into it, the first map would be modified to {a: 1, b: 2, c: 4}.

Is there a way to do this using standard library functions, or do I need to do it manually through iteration and checking for conflicting values?

Was it helpful?

Solution

There's a version of map.insert that takes two iterators. An insert fails if the item (key) is already present in the target map, so this does exactly what you want.

#include <iostream>
#include <map>

int main() { 
    std::map<char, int> stuff;

    stuff['a'] = 1;
    stuff['b'] = 2;

    std::map<char, int> stuff2;

    stuff2['b'] = 3;
    stuff2['c'] = 4;

    stuff.insert(stuff2.begin(), stuff2.end());

    for (auto i : stuff)
        std::cout << i.first << "\t" << i.second << "\n";
}

Result:

a       1
b       2
c       4

OTHER TIPS

You can do this using std::for_each and a lambda:

std::map<int, int> m1 = ...;
std::map<int, int> m2 = ...;

std::for_each(m2.begin(), m2.end(),
             [&m1](const std::pair<const int, int>& a)
             {
                 if(m1.find(a.first) == m1.end())
                    m1.insert(a);
             });

Effectively, this is just bundling up what you'd have to do manually into std::for_each and a lambda. As far as I know, there's not really any nicer way of doing what you want to achieve.

If your compiler supports emplace (which GCC 4.7 doesn't, but 4.8 does), then you can utilize that:

std::for_each(m2.begin(), m2.end(),
             [&m1](const std::pair<const int, int>& a)
             {
                 m1.emplace(a.first, a.second);
             });

emplace will preserve elements, only constructing a new element if a previous one does not exist.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top