How do I merge two maps in STL and apply a function for conflicts?
Clash Royale CLAN TAG#URR8PPP
up vote
6
down vote
favorite
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...
mapA.merge(mapB, mergePredicate);
std::cout << mapA << std::endl;
// result: mapA == 0, 1.0, 1, 3.5, 2, 2.5
return 0;
c++ merge stdmap
add a comment |Â
up vote
6
down vote
favorite
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...
mapA.merge(mapB, mergePredicate);
std::cout << mapA << std::endl;
// result: mapA == 0, 1.0, 1, 3.5, 2, 2.5
return 0;
c++ merge stdmap
Have you thought to see if the Algorythm library of c++ has the matching algorythm, because, I think could be here, now I don't use the c++, but I studied it and I remember thhat the algorythm library hase some algorythm of common use, the sort, the swap and this algorythm are templetizing
– David Marabottini
24 mins ago
add a comment |Â
up vote
6
down vote
favorite
up vote
6
down vote
favorite
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...
mapA.merge(mapB, mergePredicate);
std::cout << mapA << std::endl;
// result: mapA == 0, 1.0, 1, 3.5, 2, 2.5
return 0;
c++ merge stdmap
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...
mapA.merge(mapB, mergePredicate);
std::cout << mapA << std::endl;
// result: mapA == 0, 1.0, 1, 3.5, 2, 2.5
return 0;
c++ merge stdmap
c++ merge stdmap
edited 2 mins ago
Jarod42
110k1299175
110k1299175
asked 39 mins ago


nonsensickle
2,93311949
2,93311949
Have you thought to see if the Algorythm library of c++ has the matching algorythm, because, I think could be here, now I don't use the c++, but I studied it and I remember thhat the algorythm library hase some algorythm of common use, the sort, the swap and this algorythm are templetizing
– David Marabottini
24 mins ago
add a comment |Â
Have you thought to see if the Algorythm library of c++ has the matching algorythm, because, I think could be here, now I don't use the c++, but I studied it and I remember thhat the algorythm library hase some algorythm of common use, the sort, the swap and this algorythm are templetizing
– David Marabottini
24 mins ago
Have you thought to see if the Algorythm library of c++ has the matching algorythm, because, I think could be here, now I don't use the c++, but I studied it and I remember thhat the algorythm library hase some algorythm of common use, the sort, the swap and this algorythm are templetizing
– David Marabottini
24 mins ago
Have you thought to see if the Algorythm library of c++ has the matching algorythm, because, I think could be here, now I don't use the c++, but I studied it and I remember thhat the algorythm library hase some algorythm of common use, the sort, the swap and this algorythm are templetizing
– David Marabottini
24 mins ago
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
4
down vote
I don't know of any existing function to do this, but if you don't mind tearing apart the map you're merging from, you can make use of std::map
's merge
function (live example):
template<typename K, typename V, typename F>
void mergeWithConflicts(std::map<K, V>& base, std::map<K, V>& toMerge, F combine)
base.merge(toMerge);
// All that's left in toMerge is conflicting keys
for (const auto& [k, v] : toMerge)
base[k] = combine(base[k], toMerge[k]);
As a bonus, the implementation of merge
is rather efficient compared to what you can do by hand unless you reimplement it using the likes of extract
. Instead of copying or moving elements, it adjusts internal pointers to move nodes from one map to the other.
2
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
@Jarod42, Fair point. It depends what the expectations are in terms of conflicts vs. map size. I believe your linear approach could be made to have the same benefits rearranging nodes as well, though I'd say the tradeoff between that and this version is in code complexity.
– chris
7 mins ago
add a comment |Â
up vote
3
down vote
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);
++it2;
else // equivalent
it1->second = merger(it1->second, it2->second);
++it1;
++it2;
dest.insert(it2, source.end());
Demo
add a comment |Â
up vote
2
down vote
For this specific case, because operator
creates a key if it doesn't exist, you can use simple loop to add the two values:
for (auto pair : mapB)
mapA[pair.first] += pair.second;
And when you want to use a function, but it is okay to use a default-initialized value where no key exists:
for (auto pair : mapB)
mapA[pair.first] = mergePredicate(mapA[pair.first], pair.second);
1
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
I don't know of any existing function to do this, but if you don't mind tearing apart the map you're merging from, you can make use of std::map
's merge
function (live example):
template<typename K, typename V, typename F>
void mergeWithConflicts(std::map<K, V>& base, std::map<K, V>& toMerge, F combine)
base.merge(toMerge);
// All that's left in toMerge is conflicting keys
for (const auto& [k, v] : toMerge)
base[k] = combine(base[k], toMerge[k]);
As a bonus, the implementation of merge
is rather efficient compared to what you can do by hand unless you reimplement it using the likes of extract
. Instead of copying or moving elements, it adjusts internal pointers to move nodes from one map to the other.
2
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
@Jarod42, Fair point. It depends what the expectations are in terms of conflicts vs. map size. I believe your linear approach could be made to have the same benefits rearranging nodes as well, though I'd say the tradeoff between that and this version is in code complexity.
– chris
7 mins ago
add a comment |Â
up vote
4
down vote
I don't know of any existing function to do this, but if you don't mind tearing apart the map you're merging from, you can make use of std::map
's merge
function (live example):
template<typename K, typename V, typename F>
void mergeWithConflicts(std::map<K, V>& base, std::map<K, V>& toMerge, F combine)
base.merge(toMerge);
// All that's left in toMerge is conflicting keys
for (const auto& [k, v] : toMerge)
base[k] = combine(base[k], toMerge[k]);
As a bonus, the implementation of merge
is rather efficient compared to what you can do by hand unless you reimplement it using the likes of extract
. Instead of copying or moving elements, it adjusts internal pointers to move nodes from one map to the other.
2
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
@Jarod42, Fair point. It depends what the expectations are in terms of conflicts vs. map size. I believe your linear approach could be made to have the same benefits rearranging nodes as well, though I'd say the tradeoff between that and this version is in code complexity.
– chris
7 mins ago
add a comment |Â
up vote
4
down vote
up vote
4
down vote
I don't know of any existing function to do this, but if you don't mind tearing apart the map you're merging from, you can make use of std::map
's merge
function (live example):
template<typename K, typename V, typename F>
void mergeWithConflicts(std::map<K, V>& base, std::map<K, V>& toMerge, F combine)
base.merge(toMerge);
// All that's left in toMerge is conflicting keys
for (const auto& [k, v] : toMerge)
base[k] = combine(base[k], toMerge[k]);
As a bonus, the implementation of merge
is rather efficient compared to what you can do by hand unless you reimplement it using the likes of extract
. Instead of copying or moving elements, it adjusts internal pointers to move nodes from one map to the other.
I don't know of any existing function to do this, but if you don't mind tearing apart the map you're merging from, you can make use of std::map
's merge
function (live example):
template<typename K, typename V, typename F>
void mergeWithConflicts(std::map<K, V>& base, std::map<K, V>& toMerge, F combine)
base.merge(toMerge);
// All that's left in toMerge is conflicting keys
for (const auto& [k, v] : toMerge)
base[k] = combine(base[k], toMerge[k]);
As a bonus, the implementation of merge
is rather efficient compared to what you can do by hand unless you reimplement it using the likes of extract
. Instead of copying or moving elements, it adjusts internal pointers to move nodes from one map to the other.
edited 14 mins ago
answered 25 mins ago


chris
45k9104163
45k9104163
2
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
@Jarod42, Fair point. It depends what the expectations are in terms of conflicts vs. map size. I believe your linear approach could be made to have the same benefits rearranging nodes as well, though I'd say the tradeoff between that and this version is in code complexity.
– chris
7 mins ago
add a comment |Â
2
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
@Jarod42, Fair point. It depends what the expectations are in terms of conflicts vs. map size. I believe your linear approach could be made to have the same benefits rearranging nodes as well, though I'd say the tradeoff between that and this version is in code complexity.
– chris
7 mins ago
2
2
Note that complexity is
O(N log N)
.– Jarod42
12 mins ago
Note that complexity is
O(N log N)
.– Jarod42
12 mins ago
@Jarod42, Fair point. It depends what the expectations are in terms of conflicts vs. map size. I believe your linear approach could be made to have the same benefits rearranging nodes as well, though I'd say the tradeoff between that and this version is in code complexity.
– chris
7 mins ago
@Jarod42, Fair point. It depends what the expectations are in terms of conflicts vs. map size. I believe your linear approach could be made to have the same benefits rearranging nodes as well, though I'd say the tradeoff between that and this version is in code complexity.
– chris
7 mins ago
add a comment |Â
up vote
3
down vote
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);
++it2;
else // equivalent
it1->second = merger(it1->second, it2->second);
++it1;
++it2;
dest.insert(it2, source.end());
Demo
add a comment |Â
up vote
3
down vote
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);
++it2;
else // equivalent
it1->second = merger(it1->second, it2->second);
++it1;
++it2;
dest.insert(it2, source.end());
Demo
add a comment |Â
up vote
3
down vote
up vote
3
down vote
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);
++it2;
else // equivalent
it1->second = merger(it1->second, it2->second);
++it1;
++it2;
dest.insert(it2, source.end());
Demo
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);
++it2;
else // equivalent
it1->second = merger(it1->second, it2->second);
++it1;
++it2;
dest.insert(it2, source.end());
Demo
edited 11 mins ago
answered 17 mins ago
Jarod42
110k1299175
110k1299175
add a comment |Â
add a comment |Â
up vote
2
down vote
For this specific case, because operator
creates a key if it doesn't exist, you can use simple loop to add the two values:
for (auto pair : mapB)
mapA[pair.first] += pair.second;
And when you want to use a function, but it is okay to use a default-initialized value where no key exists:
for (auto pair : mapB)
mapA[pair.first] = mergePredicate(mapA[pair.first], pair.second);
1
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
add a comment |Â
up vote
2
down vote
For this specific case, because operator
creates a key if it doesn't exist, you can use simple loop to add the two values:
for (auto pair : mapB)
mapA[pair.first] += pair.second;
And when you want to use a function, but it is okay to use a default-initialized value where no key exists:
for (auto pair : mapB)
mapA[pair.first] = mergePredicate(mapA[pair.first], pair.second);
1
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
add a comment |Â
up vote
2
down vote
up vote
2
down vote
For this specific case, because operator
creates a key if it doesn't exist, you can use simple loop to add the two values:
for (auto pair : mapB)
mapA[pair.first] += pair.second;
And when you want to use a function, but it is okay to use a default-initialized value where no key exists:
for (auto pair : mapB)
mapA[pair.first] = mergePredicate(mapA[pair.first], pair.second);
For this specific case, because operator
creates a key if it doesn't exist, you can use simple loop to add the two values:
for (auto pair : mapB)
mapA[pair.first] += pair.second;
And when you want to use a function, but it is okay to use a default-initialized value where no key exists:
for (auto pair : mapB)
mapA[pair.first] = mergePredicate(mapA[pair.first], pair.second);
edited 25 mins ago
answered 31 mins ago
Ville-Valtteri
3,69711637
3,69711637
1
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
add a comment |Â
1
Note that complexity isO(N log N)
.
– Jarod42
12 mins ago
1
1
Note that complexity is
O(N log N)
.– Jarod42
12 mins ago
Note that complexity is
O(N log N)
.– Jarod42
12 mins ago
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53205898%2fhow-do-i-merge-two-maps-in-stl-and-apply-a-function-for-conflicts%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Have you thought to see if the Algorythm library of c++ has the matching algorythm, because, I think could be here, now I don't use the c++, but I studied it and I remember thhat the algorythm library hase some algorythm of common use, the sort, the swap and this algorythm are templetizing
– David Marabottini
24 mins ago