2015-05-19 48 views
0

我有一個叫做Object的抽象類,我使用std::unordered_map<int, Object*> objects將這些Object包含在名爲DataSet的類中。每個對象都有一個與之關聯的id從unordered_map中刪除值的有效方法,只給出值C++

通常,當從我的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; 
} 

但它似乎效率很低。那麼完成這個最有效的方法是什麼?

+0

你肯定只有一個目標匹配您的條件:這可以用find_if,這也可以用作先前算法的變化來實現?如果你需要刪除多個對象,爲什麼在第一次「擦除」之後有返回? – Steephen

+2

更重要的是,它看起來*正確*?如果價值存在多次呢?還是根本不? 'erase(kv)'不起作用。你必須用* key *擦除,而不是按值擦除,即'擦除(kv.first)'。 –

+0

我不認爲有一種有效的方法可以從地圖中刪除一個只有它的值的對象。特別是如果地圖是無序的。 –

回答

4

不要執行查找兩次;通過迭代器擦除:

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

如果你想刪除正好一個元素,你需要添加一個檢查,你發現任何針。

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! */ } 
相關問題