Is there an elegant way to overcome 2 cards and compare values ​​(cards are of the same type)

let's say I have 2 cards:

map<int,vector<int>> id2courses;
map<int,vector <int>> id2allowed_courses;

      

And I would like each key (id) to see if the course list only contains courses that are allowed for that id. This can be easily done with a for loop, but I would like to take advantage of the fact that the std :: map is ordered, since I would like to advance on both maps (increasing the iterator with a smaller key) and when I press equal keys, then I would like to make comparisons. I know I can do this with a non-trivial while loop, but I'm wondering if there is a built-in STL way to do this

+3


source to share


2 answers


Usage std::set_intersection

is a bit of a hack:

map<int,vector<int>> id2courses;
map<int,vector <int>> i2allowed_courses;

set_intersection(id2courses.begin(), id2courses.end(),
                 i2allowed_courses.begin(), i2allowed_courses.end(),
                 null_output_iterator(),
                 compare_and_do_something_if_same_key);

      

null_output_iterator

refers to the question Dropping the output of a function that requires an output iterator .

compare_and_do_something_if_same_key

will be passed a pair<const int, vector<int>>

from each mapping. If the keys are equal, you can perform the necessary processing. You also need to return a boolean to represent the ordering of the elements:

bool compare_and_do_something_if_same_key(
    pair<const int, vector<int>& a, pair<const int, vector<int>& b)
{
    if(a.first == b.first) {
        doProcessing(a, b);
    }
    return a.first < b.first;
}

      

Caveat Emptor: The documentation says that the compare function should not modify the objects being compared. I suppose this means that it should not be modified in such a way as to cause ordering problems. Since you are not ordering the value second

in pair

, I don't think this is too important.



for reading:

This can be wrapped in a named function:

template<typename Map, typename KeyValueProcessor> 
void process_values_for_matching_keys(
    Map& map1, Map& map2, KeyValueProcessor& keyValueProcessor);

      

And used like:

process_pairs_for_matching_keys(id2courses, i2allowed_courses, doProcessing);

      

+2


source


You can use set_intersection () , but this implementation, while easier to read, will not be as efficient. I would use a loop and increment two iterators over two maps. I don't think there is a faster solution. Even if there is something built in, it will perform better than this naive solution.



+1


source







All Articles