Home > Mobile >  Search inside vector of vectors
Search inside vector of vectors

Time:09-23

I have a 2D vector that i have to check if a ID already have been defined. The struct look like this

struct ExchangeStruct1 {
    std::vector<int16_t>id;
    std::vector< ObjectType_enum>type;

    std::vector<void*>source;
    std::vector<void*>destination;
    ExchangeStruct1();
};

The vector is defined as following

std::vector<std::vector<ExchangeStruct1>> exchangeList;

Is it possebile to search for the id in the second level of the vector. I tried using

it = std::find_if(exchangeList.begin(), exchangeList.end(), [key](const ExchangeStruct1>& o) -> bool {return o.id == key; });

But it only search in the first level

CodePudding user response:

With ranges::join_view this becomes trivial:

auto jv = exchangeList | std::ranges::views::join;
auto it = std::ranges::find_if(jv, [key](const ExchangeStruct1& o) {
                                       return o.id == key;
                                   });

if (it != jv.end())
{
    // ...
}

CodePudding user response:

If you only need to know if the id is present or not you can nest calls to std::find_if:

#include <vector>
#include <algorithm>
#include <iostream>
struct foo {
    int id;
};
int main() {
    std::vector<std::vector<foo>> exchangeList{ {{0},{1},{2}},{{3},{4}}};
    int target = 2;
    bool found = 
        std::find_if(exchangeList.begin(),exchangeList.end(),
                    [target](const auto& a){
                        return std::find_if(a.begin(),a.end(),[target](const auto& f){
                            return f.id == target;
                        }) != a.end();
                    }) != exchangeList.end();    
    std::cout << found;
}

However, this is a case where a handwritten nested loop is definitely more readable:

 bool find_id(const auto& exchangeList,int id) {
      for (const auto& row : exchangeList) {
          for (const auto& element : row) {
                if (element.id == id) return true;
          }
      }
      return false;
 }

This is also simpler to modify in case you do need an iterator to the found element. You'd just need to be careful to choose a sentinel to return when the element was not found. It cannot be exchangeList.end(), but you could return a std::pair< iterator to outer vector, iterator to inner vector> and return { exchangeList.end(), whatever } when no element was found.

  • Related