0

So I am doing this:

if (mp.find(3) == mp.end()) {
    cout << "3 value is there";

but it gives right for both when there is a 3 key and/or a 3 value. I just want it to return true when there is a 3 value

Alex Ren
  • 33
  • 3
  • 6
    Brute force. You iterate all of the key-value pairs in the container until you find the value as a value or hit the end of the container. – user4581301 Aug 26 '22 at 18:28
  • 3
    Side note if you want to check that something is there you should check for `!= end();` (your code does the opposite) – Borgleader Aug 26 '22 at 18:28
  • 1
    `find` only searches keys, it will return `end()` iterator if there is no key equal to `3`. It doesn't ever look at values. As user4581301 said, the only way to find a given value in `std::map`/`std::unordered_map` is brute force checking all values. – Yksisarvinen Aug 26 '22 at 18:30
  • This is not how maps work. Maps are always searched by their key value. – Sam Varshavchik Aug 26 '22 at 18:36
  • 1
    You may want boost:bimap if you want to search from either key or value: [https://www.boost.org/doc/libs/1_80_0/libs/bimap/doc/html/boost_bimap/one_minute_tutorial.html](https://www.boost.org/doc/libs/1_80_0/libs/bimap/doc/html/boost_bimap/one_minute_tutorial.html) – drescherjm Aug 26 '22 at 19:19

1 Answers1

2

Per the std::unordered_map documentation, find is looking for a key in the map. Fortunately, it's pretty simple to iterate over the pairs in a map to see if a specific value is present.

template <typename K, typename V>
bool has_value(std::unordered_map<K, V> &map, V val) {
    for (auto &[k, v] : map) {
        if (v == val) return true;
    }

    return false;
}

And then using that function:

int main() {
    std::unordered_map<int, int> map = {
        {14, 3},
        {56, 2},
        {17, 8}
    };
 
    std::cout << has_value(map, 2) << std::endl;

    return 0;
}

This will print 1.

Chris
  • 26,361
  • 5
  • 21
  • 42
  • 2
    [`std::any_of`](https://en.cppreference.com/w/cpp/algorithm/all_any_none_of) is provided for this purpose. Edit : any -> any_of – François Andrieux Aug 26 '22 at 18:37
  • 4
    I'd also note that `std::unordered_map` is not a good choice if the intent is to iterate over it. Iterating involves checking every bucket, most of them empty. If you need to iterate, it's one case where `std::map` may be more desirable. – François Andrieux Aug 26 '22 at 18:39
  • 1
    Another alternative if by-value look-up is frequent to have a separate `map` or `onordered_map` performing the reverse mapping. If you're only interested in exitance of a value, use a `set` or `unordered_set`. Put both of the containers in a wrapper class that ensures both are kept in synch. – user4581301 Aug 26 '22 at 18:44
  • Or just to use `std::find_if` instead of recreating your own bicycle. – Slava Aug 26 '22 at 19:12