How can I combine two STL cards?

How can I combine two STL cards into one? They both have the same keys and value types ( map<string, string> ). If there is a key match, I would like to give preference to one of the cards.

+61
c ++ merge stl maps stdmap
Sep 03 2018-10-09T00:
source share
5 answers

Assuming you want to save the elements in mapA and combine the elements in mapB for which there is no key in mapA :

 mapA.insert(mapB.begin(), mapB.end()) 

will do what you want, I think.

Working example:

 #include <iostream> #include <map> void printIt(std::map<int,int> m) { for(std::map<int,int>::iterator it=m.begin();it!=m.end();++it) std::cout << it->first<<":"<<it->second<<" "; std::cout << "\n"; } int main() { std::map<int,int> foo,bar; foo[1] = 11; foo[2] = 12; foo[3] = 13; bar[2] = 20; bar[3] = 30; bar[4] = 40; printIt(foo); printIt(bar); foo.insert(bar.begin(),bar.end()); printIt(foo); return 0; } 

exit:

 :!./insert 1:11 2:12 3:13 2:20 3:30 4:40 1:11 2:12 3:13 4:40 
+115
Sep 03 '10 at 21:50
source share

If you want to copy entries from one map to another, you can use std::map insert :

 targetMap.insert(sourceMap.begin(), sourceMap.end()); 

But note that insert does not update elements if their key is already in targetMap; These items will be left as is. To overwrite elements, you will need to explicitly copy, for example:

 for(auto& it : sourceMap) { targetMap[it.first] = it.second; } 

If you don't mind losing data in sourceMap , another way to achieve copying and overwriting is to insert target into the source and std::swap results:

 sourceMap.insert(targetMap.begin(), targetMap.end()); std::swap(sourceMap, targetMap); 

After replacing, sourceMap will contain old data as targetMap , and targetMap will merge the two maps with preference for sourceMap entries.

+30
Mar 06 '14 at 9:57
source share

Note that starting with C ++ 17, there is a merge() method for maps.

+12
Mar 31 '18 at 6:28
source share

According to ISO / IEC 14882: 2003, clause 23.1.2, table 69, expression a.insert (i, j):

pre: i, j are not iterators in a. inserts each element from the range [i, j) if and only if there is no element with a key equivalent to the key of this element in containers with unique keys;

Since this std :: map must follow this restriction, if you want to give preference to β€œvalues” from one map over another, you must insert into it. For example,

 std::map<int, int> goodKeys; std::map<int, int> betterKeys; betterKeys.insert(goodKeys.begin(), goodKeys.end()); 

So, if there are any equivalent keys in goodKeys and betterKeys, the "values" of the bestKeys will be saved.

+3
Mar 30 '15 at 17:15
source share

C ++ 17

As mentioned in John Perry's answer , since C ++ 17 std::map provides a member function merge() . The merge() function produces the same result for the target map as the jkerian solution, using insert() , as you can see from the following example, which I borrowed from jkerian. I just updated the code with some C ++ 11 and C ++ 17 features (such as using type alias , range-based for loop with structured binding and list initialization ):

 using mymap = std::map<int, int>; void printIt(const mymap& m) { for (auto const &[k, v] : m) std::cout << k << ":" << v << " "; std::cout << std::endl; } int main() { mymap foo{ {1, 11}, {2, 12}, {3, 13} }; mymap bar{ {2, 20}, {3, 30}, {4, 40} }; printIt(foo); printIt(bar); foo.merge(bar); printIt(foo); return 0; } 

Exit:

1:11 2:12 3:13
2:20 3:30 4:40
1:11 2:12 3:13 4:40

As you can see, merge() also gives priority to the target map foo when the keys overlap.

However, there is a difference between using insert() and merge() respect to what happens with the original map. The insert() functions add new records to the target card, and merge() moves the records from the original card. This means that in the above example, insert() does not change bar , but merge() removes 4:40 from bar , so only 2:20 and 3:30 remain in bar .

Note: I reused an example from jkerian that uses map<int, int> for brevity, but merge() also works for your map<string, string> .

Code for Colira

+2
Jun 14 '19 at 8:46
source share



All Articles