从 unordered_map 中删除值的有效方法,当只给出值 C++

Ale*_*lex 0 c++ iterator unordered-map

我有一个名为的抽象类Object,我使用std::unordered_map<int, Object*> objects将这些Objects包含在一个名为DataSet. 每个对象都有一个id与之关联的对象。

通常,当从 my 中删除对象时unordered_map,我可以执行iterator = find(id)然后调用erase该迭代器。

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

int DataSet::DeleteObject(Object* object)

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

if(object){
    for(auto kv : objects) {
        if(kv.second == object) {
            objects.erase(kv);
        }
    }
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

但这似乎非常低效。那么实现这一目标的最有效方法是什么?

Ker*_* SB 6

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

for (auto it = m.begin(); it != m.end(); )
{
    if (it->second == needle) { m.erase(it++); }
    else                      { ++it;          }
}
Run Code Online (Sandbox Code Playgroud)

这将删除所有出现的needle。如果您最多想擦除第一次出现,则可以使用更简单的循环:

for (auto it = m.begin(); it != m.end(); ++it)
{
    if (it->second == needle) { m.erase(it); break; }
}
Run Code Online (Sandbox Code Playgroud)

如果你想删除恰好一个元素,你需要添加一个检查,你发现任何针。这可以通过 来实现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! */ }
Run Code Online (Sandbox Code Playgroud)