ChrisD
ChrisD

Reputation: 674

Search for value in multi map

Suppose I have the following:

class Foo {
public:
    Foo(int x) {
        _x = x;
    }
    int _x;    
}

int main() {
    multimap<string, Foo> mm;
    Foo first_foo(5);
    Foo second_foo(10);

    mm.insert(pair<string, Foo>("A", first_foo));
    mm.insert(pair<string, Foo>("A", second_foo));

    Foo third_foo(10); 
}

What's a nice way of checking if third_foo with key "A" is already in my multimap?

Upvotes: 2

Views: 2220

Answers (3)

cwschmidt
cwschmidt

Reputation: 1204

Another alternative solution could be to use lower_bound and upper_bound methods, inside a lambda that is immediately:

bool found = [mm](const string& key,int expectVal) {
    auto ub = mm.upper_bound(key);    
    return (find_if(mm.lower_bound(key),ub,[expectVal](auto p){ return p.second._x==expectVal; }) != ub);        
}("A",third_foo._x);

Upvotes: 0

phantom
phantom

Reputation: 3342

std::find can be used to find an object in any container that can be iterated.

In your code it would look like this:

auto it = std::find(mm.begin(), mm.end(), std::pair<string, Foo>("A", third_foo));

if (it == mm.end())
    // third_foo is not in the multimap
else
    // third_foo is in the multimap

To make this you will either have to add an operator == to Foo or use a predicate with std::find_if. That would change your call to look like this:

auto it = std::find_if(mm.begin(), mm.end(), 
    [&third_foo](auto v)
    { 
        return v.second._x == third_foo._x;
    });

Upvotes: 6

Praetorian
Praetorian

Reputation: 109119

Use multimap::equal_range to fetch a range of iterators to entries that have the key "A". Then use any_of to check if any of those values compare equal to the Foo you want.

auto const& r = mm.equal_range("A");
bool found = std::any_of(r.first, r.second,
                         [&third_foo](decltype(mm)::value_type const& p) {
                             return p.second._x == third_foo._x;
                         });

Upvotes: 2

Related Questions