yegor256
yegor256

Reputation: 105053

How to find whether an element exists in std::map?

My use case:

map<string, Car> cars;
bool exists(const string& name) {
  // somehow I should find whether my MAP has a car
  // with the name provided
  return false;
} 

Could you please suggest the best and the most elegant way to do it in C++? Thanks.

Upvotes: 70

Views: 104350

Answers (11)

Tono Nam
Tono Nam

Reputation: 36048

This does not answer the question but it might be good to know. You can know if it exists by erasing it.

bool existed = cars.erase( name );

Upvotes: 0

user3624760
user3624760

Reputation:

C++20:

return cars.contains(name);

Upvotes: 4

Dr.Vendetta
Dr.Vendetta

Reputation: 15

#define itertype(v) typeof((v).begin())
itertype(cars) it = cars.find(name);
return it != cars.end();

Upvotes: 0

foo
foo

Reputation: 2111

Apart from the answers with iterator-Value from find() and comparison to .end(), there is another way: map::count.

You can call map::count(key) with a specific key; it will return how many entries exist for the given key. For maps with unique keys, the result will be either 0 or 1. Since multimap exists as well with the same interface, better compare with != 0 for existence to be on the safe side.

for your example, that's

return (cars.count(name)>0);

The advantages I see are 1. shorter code, 2. benefit from whatever optimisations the library may apply internally, using its representation details.

Upvotes: 22

D.Shawley
D.Shawley

Reputation: 59563

What about:

template <typename KeyType, typename Collection>
bool exists_in(Collection const& haystack, KeyType const& needle) {
    return std::find(haystack.begin(), haystack.end(), needle) != haystack.end();
}

template <typename K, typename V>
bool exists_in(std::map<K,V> const& haystack, K const& needle) {
    return haystack.find(needle) != haystack.end();
}

This makes exists_in work with any standard container via std::find and use a special version for std::map since it offers a more efficient searching alternative. You could add additional specializations as necessary (e.g., for std::set and others).

Upvotes: 10

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 506905

You could also use

bool exists(const string& name) {
  return cars.count(name) != 0;
} 

Upvotes: 27

Brian Roach
Brian Roach

Reputation: 76898

std::map::find(const key_type& x );

It returns map::end if the item doesn't exist.

Upvotes: 3

Rudi
Rudi

Reputation: 19940

bool exists(const std::map<std::string, Car>& cars, const std::string& name) {
  return cars.end() != cars.find(name);
}

Upvotes: 1

Tom
Tom

Reputation: 45104

Sure, use an iterator

map<string,Car>::const_iterator it = cars.find(name);
return it!=cars.end();

Upvotes: 66

kennytm
kennytm

Reputation: 523224

return cars.find(name) != cars.end();

Upvotes: 87

Mike Seymour
Mike Seymour

Reputation: 254431

bool exists(const string& name)
{
    return cars.find(name) != cars.end();
}

Upvotes: 5

Related Questions