简体   繁体   English

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

[英]Filter/copy a vector based on elements in another vector

I have a vector of elements of some type (with a name member), and I want to filter (or copy) this vector so that it contains only the elements whose name matches a list of certain names. 我有一个某种类型的元素的向量(带有name成员),并且我想过滤(或复制)此向量,以便它仅包含名称与某些名称列表匹配的元素。 So basically: "Copy the element if its name is equal to any of the names in vector<string> filter ". 基本上就是这样:“如果元素的名称等于vector<string> filter任何名称,则复制该元素”。

I've been trying stuff with std::copy_if and std::any_of , that resulted in code like below, but I couldn't get it to work, for once because any_of can't be applied in this way, and I'm unsure of what the correct tools are in this case. 我一直在尝试使用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);
}

How can I accomplish this, preferably with std:: functionality? 我如何才能做到这一点,最好使用std::功能? (C++11/14 welcome) (欢迎使用C ++ 11/14)

Above code on ideone if you want to play around. 如果您想在ideone上面的代码。

I guess this might be a good example to use ranges, but my code needs to compile on VS 2013 so I can't use https://github.com/ericniebler/range-v3 and I'm a bit hesitant to use an older ranges library, but I could be convinced otherwise. 我想这可能是使用范围的一个很好的例子,但是我的代码需要在VS 2013上编译,所以我不能使用https://github.com/ericniebler/range-v3 ,我有点犹豫使用较旧的范围库,但我可以说服其他人。

copy_if is the right choice, but your predicate is wrong, and you need to use back_inserter . 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);} );

To find something in a range, use std::find , which performs a simple linear search. 要查找某个范围内的内容,请使用std::find ,它执行简单的线性搜索。 If filter is sorted, std::binary_search can be used too. 如果filter已排序, std::binary_search也可以使用std::binary_search

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM