Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge 2 std::maps, and output the result in a 3rd map

Tags:

c++

c++11

Editing the original question, as I wanted to ask question about std::map, instead of std::vector. My mistake. Sorry.

My data is actually in 2 std::maps. I want to merge both the maps into a 3rd map.

My first and second maps contain entries with the same key. So I would like to merge data under those keys as well, into my resultant 3rd map.

So if I use std::merge, will I be loosing data from the first or second maps common entries? As I have mentioned that there are common data (values) in both the maps?

like image 453
XMarshall Avatar asked Dec 17 '15 17:12

XMarshall


People also ask

How can I merge two maps?

Alternatively, we can use Stream#concat() function to merge the maps together. This function can combine two different streams into one. As shown in the snippet, we are passed the streams of map1 and map2 to the concate() function and then collected the stream of their combined entry elements.

Can we equate 2 maps in C++?

The C++ function std::map::operator== tests whether two maps are equal or not.


1 Answers

Info for sequential containers

If vectors (or other sequential containers like list or deque) are sorted, then you can use std::set_union. There is an std::merge, in case you want to save duplicates

Code taken from linked page:

#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>

int main()
{
    std::vector<int> v1 = {1, 2, 3, 4, 5}; 
    std::vector<int> v2 = {      3, 4, 5, 6, 7}; 
    std::vector<int> dest1;

    std::set_union(v1.begin(), v1.end(),
                   v2.begin(), v2.end(),                  
                   std::back_inserter(dest1));

    for (const auto &i : dest1) {
        std::cout << i << ' ';
    }   
    std::cout << '\n';
}

Output: 1 2 3 4 5 6 7

Info for associative containers

You can add unique keys to the map (or set and their unordered counterparts) using insert method. Any key already existing in original map will not be replaced (in multiset and multimap duplicate keys will be added, use set_union discussed before if this should be avoided).

Example for map (ignoring entries with duplicate keys):

#include <map>
#include <iostream>

int main()
{
    std::map<int, int> v1 = {{1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}};
    std::map<int, int> v2 = {                {3, 2}, {4, 2}, {5, 2}, {6, 2}, {7, 2}};
    std::map<int, int> dest1 = v1;

    dest1.insert(v2.begin(), v2.end());

    for (const auto &i : dest1) {
        std::cout << i.first << ':' << i.second << ' ';
    }
    std::cout << '\n';
}

Output (first number is the key, second — which map it comes from): 1:1 2:1 3:1 4:1 5:1 6:2 7:2

If you switch maps around (set dest1 to be copy of v2 at the beginning and inser values of v1), then output will be: 1:1 2:1 3:2 4:2 5:2 6:2 7:2

Example for multimaps (entries from both maps are preserved):

#include <map>
#include <iostream>

int main()
{
    std::map<int, int> v1 = {{1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}};
    std::map<int, int> v2 = {                {3, 2}, {4, 2}, {5, 2}, {6, 2}, {7, 2}};
    std::multimap<int, int> dest1 {v1.begin(), v1.end()};

    dest1.insert(v2.begin(), v2.end());

    for (const auto &i : dest1) {
        std::cout << i.first << ':' << i.second << ' ';
    }
    std::cout << '\n';
}

Output: 1:1 2:1 3:1 3:2 4:1 4:2 5:1 5:2 6:2 7:2

Notice that you cannot use multimap exactly the same way you use maps. For example, operator[] is unavaliable. You will need to use insert to add entries, and use lower_bound or equal_range member functions to extract entries.

like image 190
Revolver_Ocelot Avatar answered Sep 18 '22 23:09

Revolver_Ocelot