0

Have in C++ analog IDictionary.ContainsKey (TKey) or List.Contains (T) from C# ?

For example I have array of elements and need to know have this array some value or not ? What is best way or best practics - without "foreach" for each element ! It will be good if it's will from std library for example.

UPD 1: In std lib have many containers, but I want to find a best way - faster, little code, less complicated and so on ...

Lookind that better desigion is std::unordered_set if going on this logic

    #include <unordered_set>

    std::unordered_set<std::string> NamesOfValues = { 
    "one", 
    "two", 
    "Date",
    "Time" 
    };

  // and now check is value exists in set
  if(NamesOfValues.count(value))
    {
        // value exists
    }
Aleksandr Zolotov
  • 1,078
  • 3
  • 19
  • 32
  • 1
    Could take a look at std::map (in particular - find() function): http://www.cplusplus.com/reference/map/map/find/ – Alfie J. Palmer Aug 03 '17 at 13:43
  • May be, I have take a look - but may be have better desigion - for example std::map::count look even better... – Aleksandr Zolotov Aug 03 '17 at 13:47
  • Possible duplicate of [Determine if map contains a value for a key?](https://stackoverflow.com/questions/3136520/determine-if-map-contains-a-value-for-a-key) – underscore_d Aug 03 '17 at 13:50
  • 1
    @underscore_d- I know that for example std lib have many containers for values like map, set and so on - I ask about better desigion and best practics for do it ! – Aleksandr Zolotov Aug 03 '17 at 14:01
  • 1
    May be you can find answer [here](https://stackoverflow.com/questions/3136520/determine-if-map-contains-a-value-for-a-key) –  May 30 '18 at 11:43

2 Answers2

2

Your are looking for std::find. Find looks for an arbitrary type input to an arbitrary iterable and returns an iterator to that element.

For example, to find an element in a dictionary you can do the following:

std::unordered_map<char,int> my_map = { {'a', 1},{'b', 2}};

auto found_element = std::find(my_map.begin(), my_map.end(), 'a');
if( found_element == my_map.end() ){
   //nothing was found
}
else{
   // do something
}

For standard map you also have map.find(T) for O(1) access instead of O(n).

if( my_map.find('a') != my_map.end() ){
   //something was found!
}
else{
   //nothing was found
}

This is more clear than my_map.count()... you would only use that if you were actually trying to figure out how many elements you have and if you were using non unique keys.

Krupip
  • 4,404
  • 2
  • 32
  • 54
  • @Alexander what do you mean by "big code", also i included an example now. There's no other standard way to do this as far as I know – Krupip Aug 03 '17 at 13:46
  • @Alexander you could wrap code like this in a boolean function and then just pass the parameters through. That way you could have something like .containsKey(...) return true or false – Alfie J. Palmer Aug 03 '17 at 13:48
  • @Alexander That doesn't make much sense if you are using unordered maps... it also would take the same amount of space, I'll edit my post to show it. – Krupip Aug 03 '17 at 13:53
2

It seems most concise to use count, and this should work for any container.

if ( my_map.count(key) ) { // shorthand for `count(key) != 0`
    // It exists
} else {
    // It does not
}

If we're talking about [unordered_]map and [unordered_]set, which are closest to your original dictionary type, then these containers enforce unique keys, so the returned .count() can only be 0 or 1, and there's no need to worry about the code pointlessly iterating the rest of the container once it finds a match (as would occur for containers supporting duplicates)

Either way, simply using implicit conversion to bool leads to the most concise code. And if you end up having a design that might allow/need different counts per key, then you could compare against a specific value.

underscore_d
  • 6,309
  • 3
  • 38
  • 64
  • May be better if (my_map.count(key) > 0) ? – Aleksandr Zolotov Aug 03 '17 at 13:50
  • 1
    I don't see why. Neither `map` nor `set` can contain more than 1 element of a given key. So the result will either be 0 or 1. Why complicate things? But if you prefer the semantics of writing `> 0`, then sure, feel free. I guess it might make the code more easily transferable to another type of container later. – underscore_d Aug 03 '17 at 13:52
  • 1
    @Alexander I updated it simply to implicitly convert the returned count to `bool`, which looks even more concise. – underscore_d Aug 03 '17 at 13:56
  • Excuse me - what is your opinion - what is beter choise in map, set , unordered_map and unordered_set ? If I don't worry about order inside array ? – Aleksandr Zolotov Aug 03 '17 at 14:14
  • 2
    Isn't it simple? If you don't care about order, then use the unordered version, so you won't be paying for forced ordering that you don't care about. If you only need a key, then don't use a map, which also has a value that you don't care about. More generally, consult [In which scenario do I use a particular STL container?](https://stackoverflow.com/questions/471432/in-which-scenario-do-i-use-a-particular-stl-container) – underscore_d Aug 03 '17 at 14:15
  • 1
    You're welcome! Enjoy C++ and the many options in the Standard Library. :D – underscore_d Aug 03 '17 at 14:16