用c ++子集一个向量

时间:2015-07-05 21:35:04

标签: c++ vector

在c ++中有一种简单的方法可以从具有特定属性的向量中提取元素吗?该向量包含我自己定义的名为“Individual”的类中的对象。

我正在寻找类似SQL中此命令的c ++的东西:

> NewVector = SELECT * FROM MyVector WHERE Age > 10

或R中的这个:

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

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

以下是这些向量的定义方式:

> vector<Individual> MyVector(20000); // this one later gets filled with stuff

> vector<Individual> NewVector(0); // i want this to be a subset of MyVector

3 个答案:

答案 0 :(得分:7)

我认为,执行此操作的惯用方法是使用std::copy_if。你给它列表中的迭代器,新列表上的插入器和谓词的函数对象。

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

编辑:请注意复制语义是您想要的。如果你在向量本身中有Individual s而不是指针,那么这将导致NewVector没有与之前相同的对象,因为它们正在被复制。通常,C ++没有(好的)方法用另一个向量共享的对象填充向量;您可能希望考虑使用vector<std::shared_ptr<Individual>>

答案 1 :(得分:1)

您可以通过以下方式执行此操作

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

答案 2 :(得分:0)

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