在c++中对向量进行子集设置

Subsetting a vector in c++

本文关键字:子集 设置 向量 c++      更新时间:2023-10-16

c++中有没有一种简单的方法可以从具有特定属性的向量中提取元素?向量包含一个名为"Individual"的类中的对象,我自己定义了这个类。

我正在寻找类似于SQL中这个命令的c++等价物:

> NewVector = SELECT * FROM MyVector WHERE Age > 10

或者R中的这个:

> NewVector <- subset(MyVector, Age > 10)

所以基本上,我想扫描MyVector的所有元素,并在它们满足条件MyVector[i].Age > 10时将它们添加到NewVector

以下是这些矢量的定义:

> vector<Individual> MyVector(20000); // this one later gets filled with stuff
> vector<Individual> NewVector(0); // i want this to be a subset of MyVector

我认为,实现这一点的惯用方法是使用std::copy_if。您给它列表上的迭代器,新列表上的插入器,以及谓词的函数对象。

类似的东西

std::copy_if(MyVector.begin(), MyVector.end(), std::back_inserter(NewVector), [] (Individual i) { return i.Age > 10; });

编辑:注意复制语义是您想要的。如果你在向量本身中有Individual,而不是指针,那么这将导致NewVector没有以前的对象,因为它们正在被复制。一般来说,C++没有(好的(方法来用与另一个向量共享的对象填充向量;您可能希望考虑CCD_ 7。

您可以通过以下方式

#include <vector>
#include <iterator>
#include <algorithm>
//...
vector<Individual> MyVector(20000); // this one later gets filled with stuff
vector<Individual> NewVector; // i want 
//...
auto older_than_10 = []( const Individual &i ) { return i.Age > 10; };
auto n = std::count_if( MyVector.begin(), MyVector.end(), older_than_10 );
NewVector.reserve( n );
std::copy_if( MyVector.begin(), MyVector.end(), 
              std::back_inserter( NewVector ), older_than_10 );
template<class F>
struct filter_t{
  F f;
  template<class T,class A>
  std::vector<T> operator()(std::vector<T,A> const& v)const{
    std::vector<T> r;
    std::copy_if( v.begin(), v.end(), std::back_inserter(r), f );
    return r;
  }
};
template<class F,class R=filter_t<std::decay_t<F>>>
R filter(F&&f){return {std::forward<F>(f)};}

从lambda生成过滤器。用途:

auto newVec = filter([](int x){return x>10;})( oldVec );