C++ 当只给出值C+时,从无序的_映射中删除值的有效方法+;

C++ 当只给出值C+时,从无序的_映射中删除值的有效方法+;,c++,iterator,unordered-map,C++,Iterator,Unordered Map,我有一个名为Object的抽象类,我使用std::unordered_map objects在名为DataSet的类中包含这些Objects。每个对象都有一个与其关联的id 通常,当从我的无序映射中删除对象时,我只需执行iterator=find(id),然后在该迭代器上调用erase 这是简单而有效的。问题是,我必须实现一种方法来按值而不是按键(这是我的id)删除条目/对。这给了我以下原型: int数据集::删除对象(对象*对象) 实现这一点最有效的方法是什么?我想我可以做这样的事情: if(

我有一个名为
Object
的抽象类,我使用
std::unordered_map objects
在名为
DataSet
的类中包含这些
Object
s。每个对象都有一个与其关联的
id

通常,当从我的
无序映射
中删除对象时,我只需执行
iterator=find(id)
,然后在该迭代器上调用
erase

这是简单而有效的。问题是,我必须实现一种方法来按值而不是按键(这是我的
id
)删除条目/对。这给了我以下原型:

int数据集::删除对象(对象*对象)

实现这一点最有效的方法是什么?我想我可以做这样的事情:

if(object){
    for(auto kv : objects) {
        if(kv.second == object) {
            objects.erase(kv);
        }
    }
    return 1;
}

但它似乎效率很低。那么,实现这一点最有效的方法是什么呢?

不要执行两次查找;通过迭代器擦除:

for (auto it = m.begin(); it != m.end(); )
{
    if (it->second == needle) { m.erase(it++); }
    else                      { ++it;          }
}
这将删除所有出现的
指针
。如果希望最多擦除第一次出现的内容,则可以使用更简单的循环:

for (auto it = m.begin(); it != m.end(); ++it)
{
    if (it->second == needle) { m.erase(it); break; }
}
如果您只想擦除一个元素,则需要添加一个检查,以确保找到任何指针。这可以通过
find_if
实现,它也可以用作先前算法的变体:

auto it = std::find_if(m.begin(), m.end(),
                       [&needle](const auto & p) { return p.second == needle; });

if (it != m.end()) { m.erase(it); }
else               { /* no such element! */ }

不要执行两次查找;通过迭代器擦除:

for (auto it = m.begin(); it != m.end(); )
{
    if (it->second == needle) { m.erase(it++); }
    else                      { ++it;          }
}
这将删除所有出现的
指针
。如果希望最多擦除第一次出现的内容,则可以使用更简单的循环:

for (auto it = m.begin(); it != m.end(); ++it)
{
    if (it->second == needle) { m.erase(it); break; }
}
如果您只想擦除一个元素,则需要添加一个检查,以确保找到任何指针。这可以通过
find_if
实现,它也可以用作先前算法的变体:

auto it = std::find_if(m.begin(), m.end(),
                       [&needle](const auto & p) { return p.second == needle; });

if (it != m.end()) { m.erase(it); }
else               { /* no such element! */ }

您确定只有一个对象与您的条件匹配吗?如果您需要删除多个对象,为什么在第一次
擦除之后会有返回?更重要的是,它看起来正确吗?如果该值存在多次怎么办?或者根本没有?而且
擦除(kv)
不起作用。你必须按键擦除,而不是按值擦除,也就是说,
擦除(kv.first)
。我认为没有一种有效的方法可以从只包含值的贴图中移除对象。特别是如果地图是无序的,那么你是对的。更新它以修复此问题您确定只有一个对象与您的条件匹配吗?如果您需要删除多个对象,为什么在第一次
擦除之后会有返回?更重要的是,它看起来正确吗?如果该值存在多次怎么办?或者根本没有?而且
擦除(kv)
不起作用。你必须按键擦除,而不是按值擦除,也就是说,
擦除(kv.first)
。我认为没有一种有效的方法可以从只包含值的贴图中移除对象。特别是如果地图是无序的,那么你是对的。更新它以修复这是一个品味问题,但我更喜欢使用
it=m.erase(it)
而不是
m.erase(it++)
这是一个品味问题,但我更喜欢使用
it=m.erase(it)
而不是
m.erase(it++)