In this article we will discuss two different ways to erase elements from map i.e.
In previous article we discussed how to erase elements by key and iterator using member function std::map::erase. But there is no default function to delete elements by value instead of key or delete elements based on callback.
We will create generic erase_if for std::map
Erasing elements by value
Algorithm Used
Iterate over all the elements and delete the elements(Key-value pairs) whose value field matches the given value.
We will create a template function that can work with all kind of map i.e. std::map<K, V> where K & V can be anything.
Complete example is as follows,
#include <iostream> #include <map> #include <string> #include <iterator> #include <vector> /* * Generic implementation to erase elements by value * It iterates over all the elements and for every element it matches * the value with the passed value, if it matches then it will delete * that entry and move to next. */ template<typename K, typename V> int erase_if(std::map<K, V> & mapOfElemen, V value) { int totalDeletedElements = 0; auto it = mapOfElemen.begin(); // Iterate through the map while (it != mapOfElemen.end()) { // Check if value of this entry matches with given value if (it->second == value) { totalDeletedElements++; // Erase the current element, erase() will return the // next iterator. So, don't need to increment it = mapOfElemen.erase(it); } else { // Go to next entry in map it++; } } return totalDeletedElements; } int main() { // Map of string & int i.e. words as key & there // occurrence count as values std::map<std::string, int> wordMap = { { "is", 6 }, { "the", 5 }, { "hat", 9 }, { "at", 6 } }; std::cout << "Map Entries Before Deletion" << std::endl; // Print the map elements for (auto elem : wordMap) std::cout << elem.first << " :: " << elem.second << std::endl; // Erase all the elements with value 6 int deletedCount = erase_if(wordMap, 6); std::cout << "Total elements deleted = " << deletedCount << std::endl; std::cout << "Map Entries After Deletion" << std::endl; // Print the map elements for (auto elem : wordMap) std::cout << elem.first << " :: " << elem.second << std::endl; return 0; }
Output:
Map Entries Before Deletion at :: 6 hat :: 9 is :: 6 the :: 5 Total elements deleted = 1 Map Entries After Deletion hat :: 9 the :: 5
Erasing elements by Callback
Algorithm Used
Iterate over all the elements and execute given callback with each element. It callback returns true then delete that element and move to next.
We will create a template function that can work with all kind of map i.e. std::map<K, V> where K & V can be anything.
Example:
Suppose we have a map of string and int. Delete all elements whose value is Odd
Complete example is as follows,
#include <iostream> #include <map> #include <string> #include <iterator> #include <vector> #include <functional> /* * Generic implementation to erase elements by Callback * It iterates over all the elements and for every element it executes * the callback, if it returns the true then it will delete * that entry and move to next. */ template<typename K, typename V> int erase_if(std::map<K, V> & mapOfElemen, bool(* functor)(V)) { int totalDeletedElements = 0; auto it = mapOfElemen.begin(); // Iterate through the map while(it != mapOfElemen.end()) { // Check if value of this entry matches with given value if(functor(it->second)) { totalDeletedElements++; // Erase the current element, erase() will return the // next iterator. So, don't need to increment it = mapOfElemen.erase(it); } else { // Go to next entry in map it++; } } return totalDeletedElements; } bool isODD(int val) { if(val % 2 == 1) return true; else return false; } int main() { // Map of string & int i.e. words as key & there // occurrence count as values std::map<std::string, int> wordMap = { { "is", 6 }, { "the", 5 }, { "hat", 9 }, { "at", 6 } }; std::cout << "Map Entries Before Deletion" << std::endl; // Print the map elements for (auto elem : wordMap) std::cout << elem.first << " :: " << elem.second << std::endl; // Erase all the elements whose value is ODD int deletedCount = erase_if(wordMap, &isODD); std::cout<<"Total elements deleted = "<<deletedCount<<std::endl; std::cout << "Map Entries After Deletion" << std::endl; // Print the map elements for (auto elem : wordMap) std::cout << elem.first << " :: " << elem.second << std::endl; return 0; }
Output:
Map Entries Before Deletion at :: 6 hat :: 9 is :: 6 the :: 5 Total elements deleted = 1 Map Entries After Deletion at :: 6 is :: 6
Pointers in C/C++ [Full Course]