根据另一个矢量中的元素过滤/复制一个矢量

Filter/copy a vector based on elements in another vector

本文关键字:复制 一个 元素 另一个 过滤      更新时间:2023-10-16

我有一个某种类型的元素向量(带有name成员),我想过滤(或复制)这个向量,使它只包含名称与特定名称列表匹配的元素。所以基本上:"如果元素的名称等于vector<string> filter中的任何名称,则复制该元素"。

我一直在尝试std::copy_ifstd::any_of,这导致了下面这样的代码,但我无法让它工作,因为any_of不能以这种方式应用,而且我不确定在这种情况下正确的工具是什么。

using namespace std;
template<class T>
struct MyType {
  string name;
  T data;
};
template<class T>
vector<MyType<T>> filter(vector<MyType<T>> items, vector<string> filter)
{
  vector<MyType<T>> filteredItems;
  copy_if(begin(items), end(items), begin(filteredItems), any_of(begin(filter), end(filter), [](const MyType<T>& lhs, const MyType<T>& rhs) {return lhs.name == rhs.name; }));
  return filteredItems;
};
int main() {
  vector<MyType<int>> items { {"a", 1}, {"b", 2}, {"c", 3} };
  vector<string> filter { "a", "c" };
  auto filteredItems = filter(items, filter);
}

如何实现这一点,最好使用std::功能?(欢迎C++11/14)

如果你想玩的话,上面的代码在表意文字上。

我想这可能是一个使用范围的好例子,但我的代码需要在VS2013上编译,所以我不能使用https://github.com/ericniebler/range-v3我有点犹豫是否要使用一个旧的范围库,但我可以说服其他人。

copy_if是正确的选择,但谓词是错误的,需要使用back_inserter

copy_if(begin(items), end(items), back_inserter(filteredItems), 
       [&](const MyType<T> & item) { return std::find(begin(filter), end(filter), item.name) != end(filter);} );

要查找某个范围内的内容,请使用std::find,它执行简单的线性搜索。如果对filter进行排序,则也可以使用std::binary_search