0

Suppose I know that a given std::multimap has exactly one element with a given key and value, and I want to delete this element.

I could explicitly write a std::multimap::find to find some element with that key, then walk backwards until I reach the first element with a different key, walk forward until I find the element I want, and delete it.

Question: Is there anything in <algorithm> or elsewhere that will do this for me? Or do I have to write my own method?


EDIT: This is not the same question as STL Multimap Remove/Erase Values, which is about removing all elements with a given value.

Daniel McLaury
  • 4,047
  • 1
  • 15
  • 37
  • 1
    [`std::multimap::erase`](https://en.cppreference.com/w/cpp/container/multimap/erase) – NathanOliver Apr 19 '21 at 18:55
  • 1
    Also, there is [`std::multimap::equal_range`](https://en.cppreference.com/w/cpp/container/multimap/equal_range) you can use to limit the search space. – NathanOliver Apr 19 '21 at 18:58
  • 1
    `equal_range` gives you the sequence of all values with the same key, which simplifies the task of finding the one to remove. There is no built-in `multimap` method that does what you want, you will have to use the ones that are available, like `equal_range`, to implement the appropriate logic yourself. – Sam Varshavchik Apr 19 '21 at 19:10

1 Answers1

0

There is no built in way to do anything involving searching by key and value but as NathanOliver says in comments, you can write a helper function on top of multimap::equal_range, e.g.

#include <map>
#include <iostream>

template<typename K, typename V>
typename std::multimap<K, V>::const_iterator find_item_by_key_and_value(const std::multimap<K, V>& mm, K k, V v) {
    auto range = mm.equal_range(k);
    return std::find_if(range.first, range.second, [v](const auto& p) {return p.second == v; });
}

template<typename K, typename V>
void erase_item_by_key_and_value( std::multimap<K, V>& mm, K k, V v) {
    auto iter = find_item_by_key_and_value(mm, k, v);
    if (iter != mm.end())
        mm.erase(iter);
}

int main()
{
    std::multimap<int, int> mm = { 
       {1,2}, {2,42}, {2,54}, {2, 37}, {42,42} 
    };

    erase_item_by_key_and_value(mm, 2, 37);

    for (const auto& [k, v] : mm) {
        std::cout << "{" << k << " , " << v << "}\n";
    }

}
jwezorek
  • 8,592
  • 1
  • 29
  • 46