从std :: vector中过滤掉元素的有效方法

geo*_*sos 7 c++ boost stl c++11

我最终得到了以下代码,以便从std :: vector中过滤掉一些不良元素:

#include <iostream>
#include <vector>
#include <algorithm>

typedef struct mystruct {
    int id;
    std::string name;
};

int main()
{        
    std::vector<mystruct> all_items = {{151, "test1"}, {154, "test4"}, {152, "test2"}, {151, "test1"}, {151, "test1"}, {153, "test3"}};
    std::vector<int> bad_ids = {151, 152};
    std::vector<mystruct> filter_items;

    for (const auto& item : all_items) {
        if ( std::find(bad_ids.begin(), bad_ids.end(), item.id) != bad_ids.end() ) {
            std::cout << "id: " << item.id << " is bad" << std::endl;
        } else {
            std::cout << "id: " << item.id << " is good item" << std::endl;
            filter_items.emplace_back(item);
        }
    }

    for (auto f : filter_items) {
        std::cout << "Good item: " << f.id << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有更有效的方法?可以在这里使用std :: remove_copy_if或Boost以及如何使用?

son*_*yao 5

是的你可以使用std :: remove_copy_if,例如

std::remove_copy_if(
  all_items.begin(), 
  all_items.end(), 
  std::back_inserter(filter_items),
  [&bad_ids](const mystruct& item) { return std::find(bad_ids.begin(), bad_ids.end(), item.id) != bad_ids.end(); });
Run Code Online (Sandbox Code Playgroud)

生活

或者你可以使用的std ::的remove_if擦除直接在向量元素,如

all_items.erase(
  std::remove_if(
    all_items.begin(), 
    all_items.end(), 
    [&bad_ids](const mystruct& item) { return std::find(bad_ids.begin(), bad_ids.end(), item.id) != bad_ids.end(); }), 
  all_items.end());
Run Code Online (Sandbox Code Playgroud)

生活


Ric*_*ges 5

扩展@songyuanyao 的正确答案,保留一个小容器助手库以使代码更具表现力永远不会有什么坏处。

#include <iostream>
#include <vector>
#include <algorithm>

struct mystruct {
    int id;
    std::string name;
};

template<class T, class A, class Pred>
std::vector<T, A> copy_unless(std::vector<T, A> container, Pred&& pred)
{
    container.erase(std::remove_if(container.begin(), container.end(), 
                                   std::forward<Pred>(pred)), 
                    container.end());
    return container;
}

template<class Container, class Pred>
bool any_match(Container&& container, Pred&& pred)
{
    return std::find_if(container.begin(), container.end(), pred) != container.end();
}

int main()
{        
    std::vector<mystruct> all_items = {{151, "test1"}, {154, "test4"}, {152, "test2"}, {151, "test1"}, {151, "test1"}, {153, "test3"}};
    std::vector<int> bad_ids = {151, 152};

    auto is_bad = [&bad_ids](mystruct const& item)
    {
        auto match_id = [&item](int id){ return item.id == id; };
        return any_match(bad_ids, match_id);
    };

    auto filter_items = copy_unless(all_items, is_bad);

    for (auto&& f : filter_items) {
        std::cout << "Good item: " << f.id << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

我确定我记得像这样的图书馆在 boost 中,但对于我的生活,我不记得它是哪个。