4
votes

I have my own object

class my_object
{
  int id;
  bool state;
  string name;
  string vendor;
}

And I would like to store my object into two map for fast enough reference.

std::map<string, my_object> map1;
std::map<string, my_object> map2;

Finally, I want to check if there are some keys of my object exist in both maps:

for(each my_object m1 in map1 and my_object m2 in map2 have the same key)
//for example, key "Bob" have corresponding objects in map1 and map2
{
  if(m1.vendor == m2.vendor)
  {
    //do some work
  }
}

How can I achieve the compare job in two maps? Or should I use a different data structure?

UPDATE: Thanks for the replies. Why I am using two maps is because two different function will produce the maps:

function1() //returns map1;
function2() //returns map2;

The key used in the both maps is the name field of my_object. For "fast enough reference", I thought that if map1 has n elements, map2 has m elements, is my computation time n*m?

3
What are the two keys in the two maps? Is one map keyed by name and the other by vendor?John Zwinck
There must be a solution but it would be so efficient. If you told us what are you trying to do, it may help.Humam Helfawi
If the same key is in both maps does that guarantee the same object?M.M
@M.M it seems not in the OP case. Which I did not find logically.Humam Helfawi
While not a direct answer to the question, you might be better served by analyzing why you have two maps in the first place - "for fast enough reference" leaves something to be desired. It may turn out that you don't really need that, or that a different container works better.Ramon

3 Answers

4
votes

You can

for (const auto& m1 : map1) {
    auto i2 = map2.find(m1.first);
    if (i2 != map2.end() && m1.second.vendor == i2->second.vendor) {
        // do some work
    }
}
3
votes

You can iterate over one of the maps (ideally you'd pick the shorter one if the number of elements could vary markedly and performance mattered), and while doing so search for each key in turn in the other map (with std::map::find).

for (const auto& kv : map1)
{
    auto it2 = map2.find(kv.first);
    if (it2 != map2.end() && kv.second.vendor == it2->second.vendor)
        ...do whatever...
}
1
votes

Here is a program that will call an arbitrary function for each key that exists in both maps. It's based on the sample implementation of std::set_intersection.

You could modify the lambda to perform your vendor equality test or whatever other check you want.

 #include <map>
 #include <string>
 #include <iostream>

 template<typename K, typename V1, typename V2, typename Func>
 void map_intersection(std::map<K,V1> const &m1, std::map<K,V2> const &m2, Func f)
 {
    auto it1 = m1.begin(), it2 = m2.begin();

    while (it1 != m1.end() && it2 != m2.end() ) {
         if (it1->first < it2->first) {
             ++it1;
         } else  {
             if (!(it2->first < it1->first)) {
                 f(it1->second, it2->second);
             }
             ++it2;
         }
     }  
 }

 int main()
 {
     std::map<std::string, std::string> map1 = { {"a", "apple"}, {"b", "bug"}, {"c", "car"} };
     std::map<std::string, std::string> map2 = { {"b", "boat"}, {"c", "car"} };

     map_intersection(map1, map2, [](std::string const &v1, std::string const &v2)
     {
         std::cout << "Same key: " << v1 << "," << v2 << '\n';
     });
 }

Output:

Same key: bug,boat
Same key: car,car