从持有std :: map元素的std :: vector中查找和擦除值

问题描述

首先,我有以下两个对象,都充满了数据:

std::vector<std::map<std::uint8_t,std::uint8_t>> x1;
std::vector<std::map<std::uint8_t,std::uint8_t>> x2;

我的目标是在x2内部(通过 key 键)进行搜索,检查x1中是否不存在x2中的任何值,然后从x1中删除它。

我尝试使用以下代码段,但无济于事(无法编译!):

for (auto i = x1.begin(); i != x1.end(); ++i)
{
    auto it = std::find(x2.begin(),x2.end(),i);
    
    if (it == x2.end())
    {
        x1.erase(i);
    }
}

我在做什么错?您能否分享一些有关如何解决此问题的见解?

解决方法

您的代码有几个问题:

  • std::find()搜索单个匹配元素,在这种情况下,这意味着您必须给它一个std::map进行搜索。但是您传递的是i迭代器本身,而不是它所引用的std::map。您需要取消引用i,例如:

    auto it = std::find(x2.cbegin(),x2.cend(),*i);

  • 在调用x1.erase(i)时,i变得无效,这意味着循环无法再使用i-不能用于++i,不能用于i != x1.end() 。您需要保存erase()返回的新迭代器,该迭代器指的是被擦除后的 next 元素。这意味着您还需要将循环逻辑更新为在调用i时不递增erase(),例如:

    for (auto i = x1.cbegin(); i != x1.cend(); )
    {
        auto it = std::find(x2.cbegin(),*i);
    
        if (it == x2.cend())
            i = x1.erase(i);
        else
            ++i;
    }
    
  • 最后,当使用std::find()时,您正在将整个std::map对象进行比较。如果您只想比较,请尝试以下类似操作:

    for (auto i = x1.cbegin(); i != x1.cend(); )
    {
        const auto &m1 = *i:
    
        auto it = std::find_if(m1.cbegin(),m1.cend(),[&](const decltype(m1)::value_type &m1_pair) { // or (const auto &m1_pair) in C++14...
                return std::find_if(x2.cbegin(),[&](const decltype(x2)::value_type &m2){ // or (const auto &m2) in C++14...
                        return m2.find(m1_pair.first) != m2.cend();
                    }
                );
            }
        );
    
        if (it == m1.cend())
            i = x1.erase(i);
        else
            ++i;
    }
    
,

您还可以使用一些功能:Playground

#include <algorithm>
#include <functional>

// removes maps from x1,that are equal to none of x2 maps 
auto remove_start = std::remove_if(x1.begin(),x1.end(),[&](const auto& x1_map){ 
  return std::none_of(x2.begin(),x2.end(),std::bind(std::equal_to(),x1_map,std::placeholders::_1)); 
});
x1.erase(remove_start,x1.end());

编辑:仅检查密钥,请将std :: equal_to更改为自定义lambda

auto keys_equal = [](auto& m1,auto& m2){ 
  return m1.size() == m2.size() 
    && std::equal(m1.begin(),m1.end(),m2.begin(),[](auto& kv1,auto& kv2){ return kv1.first == kv2.first; });
};

// removes maps from x1,that are equal to none of x2 maps 
auto remove_start = 
  std::remove_if(x1.begin(),[&](const auto& x1_map){ 
    return std::none_of(x2.begin(),std::bind(keys_equal,std::placeholders::_1)); 
  });
x1.erase(remove_start,x1.end());

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...