Dia
Dia

Reputation: 947

C++ check if an object exists in two maps

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?

Upvotes: 4

Views: 803

Answers (3)

M.M
M.M

Reputation: 141576

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

Upvotes: 1

Tony Delroy
Tony Delroy

Reputation: 106096

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...
}

Upvotes: 3

songyuanyao
songyuanyao

Reputation: 172924

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
    }
}

Upvotes: 4

Related Questions