在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
答案 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 );