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

Efficient way to delete a value from an unordered_map, when given just the value C++

我有一个名为 Object 的摘要 class,我正在使用 std::unordered_map<int, Object*> objects 将这些 Object 包含在名为 DataSet 的 class 中].每个对象都有一个与之关联的 id

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

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

int DataSet::DeleteObject(Object* object)

完成此任务的最有效方法是什么?我想我可以做这样的事情:

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;          }
}

这将删除所有出现的 needle。如果你最多想删除第一次出现的地方,一个更简单的循环就可以了:

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! */ }