798

All I want to do is to check whether an element exists in the vector or not, so I can deal with each case.

if ( item_present )
   do_this();
else
   do_that();
Antonio
  • 19,451
  • 13
  • 99
  • 197
Joan Venge
  • 315,713
  • 212
  • 479
  • 689
  • 3
    searching in a vector is very slow since you have to look at every single element of the vector so consider using a map if you're doing a lot of lookups – naumcho Feb 20 '09 at 22:31
  • 7
    @naumcho: If the vector is sorted there's always binary search, as posted below. This makes it as fast as a map and if you're only storing values (not key/value maps) then it's going to use a lot less memory. – Adam Hawes Feb 21 '09 at 01:01
  • 5
    maps are certainly not the best choice, but using set might be useful. If you need O(1) lookup time, hash_set is the way to go. – Philipp Oct 08 '10 at 08:58
  • A superb answer present on a duplicate question: http://stackoverflow.com/a/3451045/472647 – CodeMouse92 Jun 18 '15 at 03:11
  • 1
    If you're going to search multiple times for different numbers, a hash table would be more efficient. – NL628 Nov 25 '17 at 02:26
  • 1
    The answer(s) to this question do not match the title. I strongly suggest to change the title so that people who seek the answers given will find them. It is not the fault of the person who asked the question of course, but now we have this situation... The most upvoted (and accepted) answers find the element anyway (and then check if they found it). So a better title would be "How to find an item in a `std::vector`, if it exists?" Or something like that. – Carlo Wood Feb 11 '22 at 19:09

19 Answers19

1172

You can use std::find from <algorithm>:

#include <algorithm>
#include <vector>
vector<int> vec; 
//can have other data types instead of int but must same datatype as item 
std::find(vec.begin(), vec.end(), item) != vec.end()

This returns an iterator to the first element found. If not present, it returns an iterator to one-past-the-end. With your example:

#include <algorithm>
#include <vector>

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();
Anselmo GPP
  • 425
  • 2
  • 21
MSN
  • 53,214
  • 7
  • 75
  • 105
  • Using std::count instead ( std::count(...) > 0 ), would it be "faster in theory"? – Klaim Feb 21 '09 at 00:26
  • 10
    Possibly. It depends on how often you search empty vectors. – MSN Feb 21 '09 at 00:31
  • 239
    I don't see how count() could be faster than find(), since find() stops as soon as one element is found, while count() always has to scan the whole sequence. – Éric Malenfant Feb 21 '09 at 03:29
  • 1
    Actually, you'd want to use !vector.empty(). But whatever. – MSN Feb 22 '09 at 16:46
  • 128
    Don't forget to `#include ` or else you might get very strange errors like 'can't find matching function in namespace std' – rustyx Mar 02 '12 at 15:46
  • a `bool`. It's a drop in replacement (or initialization) of `item_present` in the original question. – MSN Oct 18 '12 at 23:31
  • 108
    Has it not bothered anyone that despite the STL being "object-oriented", `.find()` is still _not_ a member function of `std::vector`, as you'd expect it should be? I wonder if this is somehow a consequence of templating. – bobobobo Dec 07 '12 at 02:33
  • 85
    @bobobobo: OOP has nothing to do with members vs. non-members. And there is a widespread school of thought that if something does not have to be a member, or when it does not give any advantage when implemented as a member, than it should not be a member; `std::vector<>::find()` would not give any advantage, nor is it needed, therefore, no, it should not be a member. See also http://en.wikipedia.org/wiki/Coupling_%28computer_programming%29 – Sebastian Mach Feb 04 '13 at 13:54
  • I almost posted asking about whether this could be optimized by only calling `vector.end()` once before realizing that, first, if I'm really concerned with speed, I shouldn't be using `find()` on a vector at all, and second, that `vector.end()` being called once instead of twice is hardly any improvement at all. – ArtOfWarfare Feb 10 '13 at 20:25
  • 3
    @ArtOfWarfare due to cache locality a sorted `vector` will often be far quicker to search than a `map` or `set`. – Steve Lorimer Apr 05 '13 at 02:34
  • 4
    @ArtOfWarfare Thirdly, you may find that the `end() call is inlined by the compiler so there's no actual `call` at all but just a raw pointer. – Frerich Raabe Dec 10 '13 at 08:23
  • @phresnel: If it does not give any advantage to make find() a member of std::vector, how on earth current member functions give an advantage by being members of std::vector of std::map ?? –  Sep 09 '14 at 12:45
  • 1
    @Gasso: Nobody rated the sanity of the current members being members in this thread. I just presented that by certain school of thoughts, `find` should not be added as a member to `std::vector`; whether existing members make sense or not was not discussed, and indeed the STL is not well designed in many aspects, mainly because the lack of experience (and my post was a response to bobobobo, who implied that members are part of the OOP concept, but they are not) – Sebastian Mach Sep 11 '14 at 09:47
  • 75
    @phresnel I would argue that "when it does not give any advantage when implemented as a member" is false for this case. The advantage being a simplified and clearer interface. For example: `mvec.find(key) != mvec.cend()` is preferable to `std::find(mvec.cbegin(), mvec.cend(), key) != mvec.cend()`. – swalog Apr 29 '15 at 20:09
  • @bobobobo Referring to the section in "Containers and algorithms" within https://www.sgi.com/tech/stl/stl_introduction.html beginning with the words: "There are two important points to notice about this call to reverse." I think this sheds some light on the thinking of the designers of the STL, although one might still wonder how much this thinking predated the idea of using C++ abstract classes to define interfaces to make the linkage between algorithms and containers more evident. – koan911 May 07 '15 at 09:25
  • 1
    @MSN Why do we need != vector.end() at end to check for the element ? Doesnt find(vector.begin(), vector.end(), item) itself suffice to find the element – John Constantine Nov 26 '15 at 17:51
  • 7
    @bobobobo : The reason why the find() function is not a member of vector is that it is inefficient. When an object of the STL has a member, that means it is a useful, efficient method; it suggests that you should use it. Since find() can not be implemented efficiently for a vector, it is not a member of vector, and the suggestion is that you use a different container if you need to use find() operations. It has nothing to do with the STL being 'badly designed' as suggested in other comments. – Pascal Engeler Jan 14 '16 at 16:50
  • 1
    @PascalEngeler: I'd say, It's not so much about whether the operation is efficent or not, but about whether direct access to the internal data structure allows a more efficent implementation of the algrithm than the generic one, which uses iterators. – MikeMB Jun 08 '16 at 22:00
  • 3
    @Claudiu in c++ you can use whatever syntax you like, just takes a page of the ugliest code and [voilà](http://ideone.com/QlCCl7) – Ap31 Sep 13 '16 at 08:48
  • 4
    @ap31: that's true, but when I use code like that in production people yell at me :( – Claudiu Sep 13 '16 at 16:00
  • 2
    The error message from GCC/GXX for forgetting to `#include` the `` header when using `std::find` has even gotten worse: `error: cannot bind non-const lvalue reference of type ‘__gnu_cxx::__normal_iterator >&’ to an rvalue of type ‘__gnu_cxx::__normal_iterator >’` – Kai Petzke Feb 11 '19 at 22:26
  • I have std::vector datatype. how to use std::find for vector of any type? – Arun Mar 08 '19 at 06:09
  • 2
    @bobobobo So many differing programming paradigms all over the place make it difficult for newcomers. – tf3 Feb 20 '20 at 03:44
  • @swalog std::find does not require that the user searches the entire range. So for the member function to be equal, it would have to be: ```mvec.find(mvec.cbegin(), mvec.cend(), key) != mvec.cend()``` which isn't a particularly cleaner interface than the nonmember function. – James Mart Jun 29 '20 at 18:50
  • @James Mart: it's been a while, but looking at in now, I don't see how that is true, the implied usage being find with a single argument of element type as key, is already aware of its own range, and can stop on first match, if any. Said in a different way, the values you are suggesting should be passed, are already known in the called scope, so you can drop them and make the interface cleaner. – swalog Jun 29 '20 at 18:57
  • @swalog I'm just saying if you make the interface cleaner like that, then your member function no longer directly imitates std::find. std find intentionally takes iterators in to allow the user to define a subset of the total range to be searched – James Mart Jul 01 '20 at 14:27
  • 2
    Fair enough. However, the discussion was on the hypothetical overload that implicitly searches the whole range, and as such does not require range specifics. If, and whenever one wished to search on a range (that isn't the whole range), you'd use find, or a member function like what you mentioned. – swalog Jul 01 '20 at 14:29
  • 4
    This sucks. There should be a std::vector::contains method. – Kiruahxh Nov 12 '20 at 07:33
  • 2
    @SebastianMach I understand, that `std::vector::find()` is not implemented, as it is not better than `std::find()`. The problem is, that a programmer, that upgrades a certain data structure from `std::vector` to `std::multiset` (or `std::set`) then has to walk through the code and update every place, where a `find()` is performed. It would be nice, if the APIs of `std::(multi)set` and `std::vector` would be as similiar as possible. – Kai Petzke Dec 07 '20 at 15:52
  • This solution does not work for `std::vector` and other pimpl expressions. Does anyone know how to make it work?? –  Apr 09 '21 at 23:57
  • 1
    The idea of OO comes from Heidegger, and is a concept of how humans perceive the world and organize information. OO design is about structuring code in a way which is easy for humans to understand. As such, container objects (like `vector`) should mimic the concept of containers in the real world. The fact that I have to say what type of objects a container can hold (the template parameter) doesn't match the real world, where containers can hold anything provided there's enough space. And since finding things in containers is a common thing to do, it should be part of the container interface. – bitjeep Jun 18 '21 at 15:49
  • 1
    It's annoying to use one pattern for std::map which does have find, then a more clunky pattern for std::vector because it does not have find. Consistency between containers would be nice, – Dave S Jun 08 '22 at 22:55
134

As others have said, use the STL find or find_if functions. But if you are searching in very large vectors and this impacts performance, you may want to sort your vector and then use the binary_search, lower_bound, or upper_bound algorithms.

Brian Neal
  • 31,821
  • 7
  • 55
  • 59
58

If your vector is not ordered, use the approach MSN suggested:

if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
      // Found the item
}

If your vector is ordered, use binary_search method Brian Neal suggested:

if(binary_search(vector.begin(), vector.end(), item)){
     // Found the item
}

binary search yields O(log n) worst-case performance, which is way more efficient than the first approach. In order to use binary search, you may use qsort to sort the vector first to guarantee it is ordered.

hfossli
  • 22,616
  • 10
  • 116
  • 130
spiralmoon
  • 3,084
  • 2
  • 25
  • 26
  • 4
    Don't you mean `std::sort`? `qsort` is very inefficient on vectors.... see: http://stackoverflow.com/questions/12308243/trying-to-use-qsort-with-vector – Jason R. Mick Aug 16 '13 at 01:57
  • 1
    Binary search will perform better for larger containers, but for small containers a simple linear search is likely to be as fast, or faster. – BillT Mar 31 '17 at 14:07
  • @BillT: Wouldn't a decent binary search implementation switch itself to linear search below some threshold number of elements? – einpoklum Jan 09 '22 at 21:40
53

Use find from the algorithm header of stl.I've illustrated its use with int type. You can use any type you like as long as you can compare for equality (overload == if you need to for your custom class).

#include <algorithm>
#include <vector>

using namespace std;
int main()
{   
    typedef vector<int> IntContainer;
    typedef IntContainer::iterator IntIterator;

    IntContainer vw;

    //...

    // find 5
    IntIterator i = find(vw.begin(), vw.end(), 5);

    if (i != vw.end()) {
        // found it
    } else {
        // doesn't exist
    }

    return 0;
}
isanae
  • 3,253
  • 1
  • 22
  • 47
m-sharp
  • 16,443
  • 1
  • 26
  • 26
29

In C++11 you can use any_of. For example if it is a vector<string> v; then:

if (any_of(v.begin(), v.end(), bind(equal_to<string>(), _1, item)))
   do_this();
else
   do_that();

Alternatively, use a lambda:

if (any_of(v.begin(), v.end(), [&](const std::string& elem) { return elem == item; }))
   do_this();
else
   do_that();
L. F.
  • 19,445
  • 8
  • 48
  • 82
Deqing
  • 14,098
  • 15
  • 84
  • 131
  • 2
    `bind1st` and `bind2nd` are [deprecated since C++11](https://en.cppreference.com/w/cpp/utility/functional/bind12) and completely removed in C++17. Use `bind` with `placeholders` and/or lambdas instead. – andreee Apr 30 '19 at 07:50
  • 4
    Why use `std::any_of()` when we have `std::find()`? – einpoklum Jan 09 '22 at 21:34
  • 2
    If the purpose is to check for membership only, why use `std::find()` when we have `std::any_of`? – Bex Mar 25 '22 at 09:30
  • 1
    @einpoklum std::find is only for C++20. Not all projects are using C++20 already. Don't think that's that easy to migrate big professional projects from one version to another. Believe me. – Maf Feb 10 '23 at 06:20
  • 1
    @Maf: Fair point, I was under the illusion it was older. – einpoklum Feb 10 '23 at 12:19
24

I use something like this...

#include <algorithm>


template <typename T> 
const bool Contains( std::vector<T>& Vec, const T& Element ) 
{
    if (std::find(Vec.begin(), Vec.end(), Element) != Vec.end())
        return true;

    return false;
}

if (Contains(vector,item))
   blah
else
   blah

...as that way it's actually clear and readable. (Obviously you can reuse the template in multiple places).

Community
  • 1
  • 1
Andy Krouwel
  • 1,309
  • 11
  • 21
  • and you can make it work for lists or vectors by using 2 typenames – Erik Aronesty Mar 03 '15 at 15:36
  • @ErikAronesty you can get away with 1 template argument if you use `value_type` from the container for the element type. I've added an answer like this. –  Feb 11 '16 at 21:40
  • 7
    You are basically writing : `if true return true else return false`. The method can be one lined in : `return std::find(Vec.begin(), Vec.end(), Element) != Vec.end();` – Charles Gueunet Oct 08 '20 at 07:52
15

Here's a function that will work for any Container:

template <class Container> 
const bool contains(const Container& container, const typename Container::value_type& element) 
{
    return std::find(container.begin(), container.end(), element) != container.end();
}

Note that you can get away with 1 template parameter because you can extract the value_type from the Container. You need the typename because Container::value_type is a dependent name.

  • 5
    Note that this is sometimes a bit too broad - it'd work for std::set for example, but give terrible performance compared to the find() member function. I've found it best to add a specialisation for containers with a faster search (set/map, unordered_*) – Andy Krouwel Nov 02 '16 at 12:01
  • 1
    Maybe one day they'll finally add this to the stdlib... instead of people having to ask how to reinvent such a tiny wheel over and over again. It's totally viable now that in C++20 we have `ranges`, so that could just be called `Range` rather than `Container`, and Bob's your uncle. – underscore_d Jul 01 '20 at 16:06
  • What do you think about @PascalLaferrière 's [approach](https://stackoverflow.com/a/58593692/1593077) of deducing the value type? – einpoklum Jan 09 '22 at 21:39
11

Bear in mind that, if you're going to be doing a lot of lookups, there are STL containers that are better for that. I don't know what your application is, but associative containers like std::map may be worth considering.

std::vector is the container of choice unless you have a reason for another, and lookups by value can be such a reason.

David Thornley
  • 56,304
  • 9
  • 91
  • 158
  • Even with lookups by value the vector can be a good choice, as long as it is sorted and you use binary_search, lower_bound or upper_bound. If the contents of the container changes between lookups, vector is not very good because of the need to sort again. – Renze de Waal Feb 20 '09 at 22:49
9

With boost you can use any_of_equal:

#include <boost/algorithm/cxx11/any_of.hpp>

bool item_present = boost::algorithm::any_of_equal(vector, element);
Mikhail
  • 20,685
  • 7
  • 70
  • 146
9

Use the STL find function.

Keep in mind that there is also a find_if function, which you can use if your search is more complex, i.e. if you're not just looking for an element, but, for example, want see if there is an element that fulfills a certain condition, for example, a string that starts with "abc". (find_if would give you an iterator that points to the first such element).

Frank
  • 64,140
  • 93
  • 237
  • 324
9

From C++20, using ranges (#include <ranges>)

    //SAMPLE DATA
    std::vector<int> vecOfElements = { 2,4,6,8 };

    //DO SOMETHING IF 8 IN VECTOR
    if (std::ranges::find(vecOfElements, 8) != vecOfElements.end())
    {
        std::cout << "DO SOMETHING" << std::endl;
    }
Pavan Chandaka
  • 11,671
  • 5
  • 26
  • 34
6

You can try this code:

#include <algorithm>
#include <vector>

// You can use class, struct or primitive data type for Item
struct Item {
    //Some fields
};
typedef std::vector<Item> ItemVector;
typedef ItemVector::iterator ItemIterator;
//...
ItemVector vtItem;
//... (init data for vtItem)
Item itemToFind;
//...

ItemIterator itemItr;
itemItr = std::find(vtItem.begin(), vtItem.end(), itemToFind);
if (itemItr != vtItem.end()) {
    // Item found
    // doThis()
}
else {
    // Item not found
    // doThat()
}
TrungTN
  • 2,412
  • 1
  • 14
  • 4
5

You can use the find function, found in the std namespace, ie std::find. You pass the std::find function the begin and end iterator from the vector you want to search, along with the element you're looking for and compare the resulting iterator to the end of the vector to see if they match or not.

std::find(vector.begin(), vector.end(), item) != vector.end()

You're also able to dereference that iterator and use it as normal, like any other iterator.

TankorSmash
  • 12,186
  • 6
  • 68
  • 106
4
template <typename T> bool IsInVector(const T & what, const std::vector<T> & vec)
{
    return std::find(vec.begin(),vec.end(),what)!=vec.end();
}
user3157855
  • 714
  • 2
  • 9
  • 24
  • If you want to adapt `std::find()` to be usable with containers, do it generically rather than for just a vector. And maybe call it `find()` or `stdx::find()` or something. – einpoklum Jan 09 '22 at 21:34
4

You can use count too. It will return the number of items present in a vector.

int t=count(vec.begin(),vec.end(),item);
Pang
  • 9,564
  • 146
  • 81
  • 122
Aditya
  • 371
  • 3
  • 8
3

I've personally used templates of late to handle multiple types of containers at once rather than deal only with vectors. I found a similar example online (can't remember where) so credit goes to whoever I've pilfered this from. This particular pattern seems to handle raw arrays as well.

template <typename Container, typename T = typename std::decay<decltype(*std::begin(std::declval<Container>()))>::type>
bool contains(Container && c, T v)
{
    return std::find(std::begin(c), std::end(c), v) != std::end(c);
}
  • Please consider separating the value-type-deduction logic into its own trait, e.g. `template struct value_type { ... etc. ... }` – einpoklum Jan 09 '22 at 21:36
  • @einpoklum I'm quite new to template logic and to be honest, I'm barely able to understand how this solution does its magic. Could you possible expand on the {...etc...}? – Pascal Laferrière Feb 07 '22 at 20:40
2

(C++17 and above):

can use std::search also

This is also useful for searching sequence of elements.

#include <algorithm>
#include <iostream>
#include <vector>

template <typename Container>
bool search_vector(const Container& vec, const Container& searchvec)
{
    return std::search(vec.begin(), vec.end(), searchvec.begin(), searchvec.end()) != vec.end();
}

int main()
{
     std::vector<int> v = {2,4,6,8};

     //THIS WORKS. SEARCHING ONLY ONE ELEMENT.
     std::vector<int> searchVector1 = {2};
     if(search_vector(v,searchVector1))
         std::cout<<"searchVector1 found"<<std::endl;
     else
         std::cout<<"searchVector1 not found"<<std::endl;

     //THIS WORKS, AS THE ELEMENTS ARE SEQUENTIAL.
     std::vector<int> searchVector2 = {6,8};
     if(search_vector(v,searchVector2))
         std::cout<<"searchVector2 found"<<std::endl;
     else
         std::cout<<"searchVector2 not found"<<std::endl;

     //THIS WILL NOT WORK, AS THE ELEMENTS ARE NOT SEQUENTIAL.
     std::vector<int> searchVector3 = {8,6};
     if(search_vector(v,searchVector3))
         std::cout<<"searchVector3 found"<<std::endl;
     else
         std::cout<<"searchVector3 not found"<<std::endl;
}

Also there is flexibility of passing some search algorithms. Refer here.

https://en.cppreference.com/w/cpp/algorithm/search

Pavan Chandaka
  • 11,671
  • 5
  • 26
  • 34
  • 2
    std::search is for searching for any of _multiple_ values in a range; for a single value, there's no reason to use it. – einpoklum Jan 09 '22 at 21:38
1

If you wanna find a string in a vector:

struct isEqual
{
    isEqual(const std::string& s): m_s(s)
    {}

    bool operator()(OIDV* l)
    {
        return l->oid == m_s;
    }

    std::string m_s;
};

struct OIDV
{
    string oid;
//else
};

VecOidv::iterator itFind = find_if(vecOidv.begin(), vecOidv.end(), isEqual(szTmp));
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Gank
  • 4,507
  • 4
  • 49
  • 45
-1

Another way to do it is using std::count.

Example code:

#include <algorithm>
#include <vector>

void run_vector_contains_example() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    int item_to_find = 3;

    int count = std::count(vec.begin(), vec.end(), item_to_find);

    if (count > 0) {
        // item found in vector
    } else {
        // item not found in vector
    }
}

Admittedly, this method might be slower than std::find when dealing with large vectors.

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185