Joan Venge
Joan Venge

Reputation: 331350

How to find out if an item is present in a std::vector?

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();

Upvotes: 840

Views: 1609143

Answers (21)

Mikhail
Mikhail

Reputation: 21799

In C++23 we finally have a decent solution:

if (std::ranges::contains(vec, item))
   do_this();
else
   do_that();

Upvotes: 27

MSN
MSN

Reputation: 54634

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-last. With your example:

#include <algorithm>
#include <vector>

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();

Upvotes: 1239

GPrathap
GPrathap

Reputation: 7820

How about this way?

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

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

// Find element 3 in the vector
auto it = std::find(vec.begin(), vec.end(), 3);

// Check if element is found
if (it != vec.end()) {
    // Calculate index of the found element
    int index = std::distance(vec.begin(), it);
    std::cout << "Element 3 found at index: " << index << std::endl;
} else {
    std::cout << "Element 3 not found" << std::endl;
}

return 0;
}

Upvotes: -1

BullyWiiPlaza
BullyWiiPlaza

Reputation: 19225

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.

Upvotes: -1

Gank
Gank

Reputation: 4667

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));

Upvotes: 0

Pavan Chandaka
Pavan Chandaka

Reputation: 12801

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;
    }

Upvotes: 17

Damian Winnicki
Damian Winnicki

Reputation: 792

template <typename T> bool IsInVector(const T & what, const std::vector<T> & vec)
{
    return std::find(vec.begin(),vec.end(),what)!=vec.end();
}

Upvotes: 3

Deqing
Deqing

Reputation: 14652

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();

Upvotes: 30

Pascal Laferri&#232;re
Pascal Laferri&#232;re

Reputation: 109

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);
}

Upvotes: 3

Pavan Chandaka
Pavan Chandaka

Reputation: 12801

(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

Upvotes: 2

user325117
user325117

Reputation:

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.

Upvotes: 15

m-sharp
m-sharp

Reputation: 17135

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;
}

Upvotes: 54

Mikhail
Mikhail

Reputation: 21799

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);

Upvotes: 11

spiralmoon
spiralmoon

Reputation: 3272

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.

Upvotes: 60

Aditya
Aditya

Reputation: 399

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

int t=count(vec.begin(),vec.end(),item);

Upvotes: 3

TankorSmash
TankorSmash

Reputation: 12777

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.

Upvotes: 5

Andy Krouwel
Andy Krouwel

Reputation: 1409

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).

Upvotes: 24

Brian Neal
Brian Neal

Reputation: 32399

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.

Upvotes: 142

TrungTN
TrungTN

Reputation: 2462

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()
}

Upvotes: 6

David Thornley
David Thornley

Reputation: 57066

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.

Upvotes: 11

Frank
Frank

Reputation: 66224

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).

Upvotes: 9

Related Questions