【问题标题】:Filter/copy a vector based on elements in another vector根据另一个向量中的元素过滤/复制一个向量
【发布时间】:2015-02-19 09:49:56
【问题描述】:

我有一个包含某种类型元素的向量(带有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)

Above code on ideone if you want to play around.

我想这可能是使用范围的一个很好的例子,但我的代码需要在 VS 2013 上编译,所以我不能使用 https://github.com/ericniebler/range-v3,而且我有点犹豫是否要使用旧的范围库,但我可以否则就被说服了。

【问题讨论】:

    标签: c++ c++11 stl std


    【解决方案1】:

    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也可以使用。

    【讨论】:

    • 非常感谢。哇,我应该能够自己想出这个!我太专注于any_of和朋友,并没有考虑find
    猜你喜欢
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 2020-10-18
    • 1970-01-01
    相关资源
    最近更新 更多