This is a simple program consisting of adding an element into the std::unordered_map
. But before it's added, first check if the key already exists, if it does then don't add it.
My problem is that since find_if
requires only one parameter to be passed in the lambda function, I'm having trouble implementing this since an element on the std::unordered_map
is a pair of two types. I wonder if it's even possible to use find_if
and if not what's the best way to accomplish this?
#include <iostream>
#include <unordered_map>
std::unordered_map <std::string_view, int> myDictionary{};
void addEmployee(std::string_view newName, int newTime)
{
// first check if they name already exists, if it does then do nothing and return
auto it{std::find_if(myDictionary.begin(), myDictionary.end(),
[&newName]( ??? )
{
return newName == myDictionary.first;
})};
if (it != myDictionary.end() )
{
std::cout << "Name already exists! Wasn't added.\n";
return;
}
// add employee into the map
myDictionary.insert(std::pair<std::string_view,int> (newName, newTime) );
}
void printDict( std::unordered_map<std::string_view, int>& myDict)
{
for (auto const& a: myDict)
std::cout << a.first << " " << a.second << "\n";
}
int main()
{
addEmployee("Daniel", 14);
addEmployee("Marco", 433);
addEmployee("Daniel", 500); //Should not add it, since key already exists
addEmployee("Alan", 125);
printDict(myDictionary);
return 0;
}
My research so far, and opens questions that I'm still trying to figure out:
std::unordered_map
only add uniques keys, it will not add it anyways if I directly insert it, so no need for a check before it (?)std::unordered_map
, I only found find
as member function, not find_if
, so I'm assuming this is why it cannot be used. If not, then is find
the best way to implement this program or using some other alternative like []
work better. (?)Thanks a lot
Since the name is the key in your unordered_map
, you can simply use the unordered_map::find
method to check whether it exists:
void addEmployee(std::string_view newName, int newTime)
{
// first check if they name already exists, if it does then do nothing and return
auto it = myDictionary.find(newName);
if (it != myDictionary.end())
{
std::cout << "Name already exists! Wasn't added.\n";
return;
}
// add employee into the map
myDictionary.insert(std::pair<std::string_view, int>(newName, newTime));
}
Some notes for completeness:
find_if
can also be used, but I see no advantage of using it over the straightforward find
method (which is designed exactly for this purpose - search for an entry by key). An example is shown in the answer by @Yksisarvinen (see that answer also for another alternative - using insert
by itself).std::string_view
does not own the string it refers to. It's OK in your case (as posted) because you used string literals but if you need to create new strings it will be more robust to use std::string
s as keys.