66

I've got a list of elements, say, integers and I want to check if my variable (another integer) is one of the elements from the list. In python I'd do:

my_list = [1,2,3,4] # elements
my_var = 3 # my variable
my_var in my_list # returns boolean

How to do that in C++? I thought of using std::list, but I can find no find method in it. I can see such method in std::set structure.

More deeply, the problem is that my program is given some unique ids (a list, a set, whatever) and I iterate over a long list of input data (ids) and check if they are included in the list (boolean value returned for each iteration step). And I'm not sure how should I do that in C++.

GG.
  • 21,083
  • 14
  • 84
  • 130
ducin
  • 25,621
  • 41
  • 157
  • 256
  • 3
    std::vector. In c++ use std::vector unless you have special reason not to. – user1937198 Jun 10 '14 at 11:07
  • `std::find` is tthe way to look for elements in a container – Andro Jun 10 '14 at 11:08
  • 1
    Why use a vector if you're looking up values? Surely you'd want a `std::set` or `std::multiset` to give better performance than a linear search unless your list is tiny or you're using a sparse vector and keying on index. – Component 10 Jun 10 '14 at 11:10
  • 1
    my list/set would be rather tiny (several elements, less than 10). – ducin Jun 10 '14 at 11:14
  • 2
    std::find better because it's independent of the container. – ABu Sep 19 '16 at 13:38

8 Answers8

111

You can use std::find

bool found = (std::find(my_list.begin(), my_list.end(), my_var) != my_list.end());

You need to include <algorithm>. It should work on standard containers, vectors lists, etc...

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
Matzi
  • 13,770
  • 4
  • 33
  • 50
  • 141
    ..concise as always with C++. Who needs a trivial method like `contains()`?! – Jay Jun 13 '16 at 10:23
  • @Alex: Fixed the naming. – Matzi Jun 17 '17 at 22:49
  • 9
    I feel like adding support for C#-style extension methods would easily fix every complaint I ever made about C++. – BTownTKD Nov 09 '17 at 18:44
  • @Jay STL must cover all use cases but be as easy as possible to port between the 70-something platforms C++ runs on. `contains` would be one more method to support that doesn't add any functionality. You're looking for something like Boost. – c z Nov 09 '20 at 10:28
  • 4
    c++ solution as usual catastrophic. – bmi Jan 03 '21 at 11:27
31

std::list does not provide a search method. You can iterate over the list and check if the element exists or use std::find. But I think for your situation std::set is more preferable. The former will take O(n) time but later will take O(lg(n)) time to search.

You can simply use:

int my_var = 3;
std::set<int> mySet {1, 2, 3, 4};
if(mySet.find(myVar) != mySet.end()){
      //do whatever
}
Markus Dutschke
  • 9,341
  • 4
  • 63
  • 58
Rakib
  • 7,435
  • 7
  • 29
  • 45
  • 5
    `myset.count(myVar) != 0` might be preferable – Tom Tanner Nov 23 '15 at 17:33
  • std::vector is preferable then - as it will in most cases be quite a bit faster. Don't get fooled just by the Big-O notation, it tells you nothing about the actual speed. Ifthe vector is sorted it is in general quite a bit faster than set.... and if you are even considering using a set then that also means you can just sort your vector anyways. – ABaumstumpf Jan 29 '21 at 09:44
9

you must #include <algorithm>, then you can use std::find

Radu Chivu
  • 1,057
  • 7
  • 17
9

They really should add a wrapper. Like this:

namespace std
{
    template<class _container,
        class _Ty> inline
        bool contains(_container _C, const _Ty& _Val)
        {return std::find(_C.begin(), _C.end(), _Val) != _C.end(); }
};
...
    if( std::contains(my_container, what_to_find) )
    {

    }
KungPhoo
  • 516
  • 4
  • 18
5

A one-liner solution, similar to python, would be (std::set<int> {1, 2, 3, 4}).count(my_var) > 0.

Minimal working example

int my_var = 3;
bool myVarIn = (std::set<int> {1, 2, 3, 4}).count(my_var) > 0;
std::cout << std::boolalpha << myVarIn << std::endl;

prints true or false dependent of the value of my_var.

Markus Dutschke
  • 9,341
  • 4
  • 63
  • 58
1

Use std::find, something like:

if (std::find(std::begin(my_list), std::end(my_list), my_var) != std::end(my_list))
    // my_list has my_var
Paul Evans
  • 27,315
  • 3
  • 37
  • 54
1

Declare additional helper function like this:

template <class T, class I >
bool vectorContains(const vector<T>& v, I& t)
{
    bool found = (std::find(v.begin(), v.end(), t) != v.end());
    return found;
}

And use it like this:

void Project::AddPlatform(const char* platform)
{
    if (!vectorContains(platforms, platform))
        platforms.push_back(platform);
}

Snapshot of example can be found here:

https://github.com/tapika/cppscriptcore/blob/b7f3d62747494a52a440482e841ffb016a3fc56e/SolutionProjectModel/Project.cpp#L13

TarmoPikaro
  • 4,723
  • 2
  • 50
  • 62
0

Since C++20 you can use l.contains(my_var)

https://www.modernescpp.com/index.php/more-convenience-functions-for-containers-with-c-20

ZyReS
  • 9
  • 1
  • 1
    You should mention that this only works for associative containers, like `set`, `map`, etc. It won't work for other containers, such as `vector`. – cigien Mar 13 '22 at 14:56
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/31277856) – Abhishek Dutt Mar 16 '22 at 02:24