【问题标题】:How to erase elements from a vector based on a specific condition in c++11如何根据c ++ 11中的特定条件从向量中擦除元素
【发布时间】:2016-04-10 00:25:45
【问题描述】:

我有一个对象向量,我想删除一些对象,而不重新排序。

我在这里找到了一些解决方案,但这些解决方案是基于将矢量元素与值进行比较。 [How to erase a value efficiently from a sorted vector?

但是,我需要根据条件语句进行擦除,所以我认为我不能按原样使用这些函数。

在这个例子中,我有一个 3D 向量的向量 我需要删除所有 Z 值小于 0 的元素;

我现在拥有的是从原始向量创建的另一个向量:

for (int i = 0; i < original_vectors.size(); i++)
        if (original_vectors[i].z > 0)
            new_vectors.push_back(original_vectors[i]);

我可以做些什么来简单地删除不具有 Z > 0 的元素?

【问题讨论】:

  • 你说你想删除所有 Z 值小于 0 的元素,但是你的代码示例删除了 Z &lt;= 0

标签: c++ c++11 vector std


【解决方案1】:

您想erase-remove idiom,这是从支持条件的 STL 容器中删除元素的标准方法。此代码 sn-p 将删除所有 predicate 返回 true 的向量元素:

vector.erase(std::remove_if(vector.begin(), vector.end(), predicate), vector.end());

检查z &lt; 0 是否为的谓词:

auto predicate = [](const vec3 &v) { return v.z < 0; }

【讨论】:

  • 谢谢,我选择了这个答案,因为它是最优雅的,但我确信其他答案是正确的。我不得不稍微修改一下:vectors.erase(std::remove_if(vectors.begin(), vectors.end(), [](const Vector3 &v) { return vz
【解决方案2】:

使用erase-remove 成语。您需要使用 lambda 表达式调用 std::remove_if,当 z &lt; 0 时返回 true。

original_vectors.erase(std::remove_if(original_vectors.begin(),
                                      original_vectors.end(),
                                      [](decltype(original_vectors)::value_type const& elem) {
                                          return elem.z < 0;
                                      },
                       original_vectors.end());

【讨论】:

  • @T.C.今天在 VS2015 中可用:)
  • @melak 考虑到 STL 提出它并不奇怪 :)
  • @melak47,我希望他们有适当的 constexpr 支持。
【解决方案3】:

如果您可以使用 boost 库,编写 remove_if/erase 习惯用法可能更优雅的方法是使用 boost 的 remove_erase_if

代码如下所示:

boost::range::remove_erase_if(original_vector,
                              [](vector_element_type t) -> bool {
                                return t.z <= 0;
                             });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多