C++ Map: Erase by Value or Callback while iterating | erase_if for map

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

 

 

 

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top