How to find if a given key exists in a C++ std::map
Use map::find
and map::end
:
if (m.find("f") == m.end()) {
// not found
} else {
// found
}
Determine if map contains a value for a key?
Does something along these lines exist?
No. With the stl map class, you use ::find()
to search the map, and compare the returned iterator to std::map::end()
so
map<int,Bar>::iterator it = m.find('2');
Bar b3;
if(it != m.end())
{
//element found;
b3 = it->second;
}
Obviously you can write your own getValue()
routine if you want (also in C++, there is no reason to use out
), but I would suspect that once you get the hang of using std::map::find()
you won't want to waste your time.
Also your code is slightly wrong:
m.find('2');
will search the map for a keyvalue that is '2'
. IIRC the C++ compiler will implicitly convert '2' to an int, which results in the numeric value for the ASCII code for '2' which is not what you want.
Since your keytype in this example is int
you want to search like this: m.find(2);
checking if key exist in map then updating value
else if ( it == two.end() )
{
it->second = it->second + 1.0;
Above line of code need to correct as follows
else if ( it != two.end() )
^^^
{
it->second = it->second + 1.0;
More than that:
it = two.find(string(pairs[i]) );
Above line can rewrite as follows
it = two.find(pairs[i] );
How to check if a value exists within a C++ Map
valueFinder
is just an iterator for the type std::map<int,int>
that is not associated to any instance of that type.
To associate it to an instance (here fibonacci_storage) you have to assign it to that instance, i.e.
valueFinder = fibonacci_storage.begin();
Finding an element can be done with source
valueFinder = fibonacci_storage.find(value);
where value is the key you are searching for. Now you check if value is in the map:
if( valueFinder != fibonacci_storage.end() )
{
// value found
}
and you're done.
How to find an element in std::map with structures that has at least one data member equal to the key
std::map
is defined only in terms of the operator<
. Two map entries are considered equal if and only if !(a < b)
and !(b < a)
. Your operator==
is not helping here, and all the find()
call is doing is finding the person with the ID you specified (or name in the second case) because it only considers operator<
.
The bigger picture is that std::map::find
makes use of the sortedness of std::map
(generally implemented as a red black tree) to avoid having to check each element. This property is not helpful if both name and ID participate in your search, because you can't tell if a matching name or is before or after any given node in the tree - you only know that for the ID (or, in the second case, the name).
Unless you want to implement a very fancy and complex way of combining the name and ID into a single sortable/searchable field (no idea how you would do that), you will have to check each element. std::find_if
does that for you:
std::find_if(phonebook.begin(), phonebook.end(), [name, id](const std::pair<Person, std::string>& personAndNumber) {
const Person& person = personAndNumber.first;
return person.name == name || person.id == id;
});
Searching std::map in O(n) for a partial key
In c++14 you can use the overload to search on a partial key:
struct CompareFirstTwo {
using is_transparent = void;
bool operator()(const tuple<A, B, C>& lhs, const tuple<A, B, C>& rhs) const ...
bool operator()(const tuple<A, B>& lhs, const tuple<A, B, C>& rhs) const ...
bool operator()(const tuple<A, B, C>& lhs, const tuple<A, B>& rhs) const ...
};
Use the comparator above in a call to equal_range
to ignore the third field in the tuple.
How to retrieve all keys (or values) from a std::map and put them into a vector?
While your solution should work, it can be difficult to read depending on the skill level of your fellow programmers. Additionally, it moves functionality away from the call site. Which can make maintenance a little more difficult.
I'm not sure if your goal is to get the keys into a vector or print them to cout so I'm doing both. You may try something like this:
std::map<int, int> m;
std::vector<int> key, value;
for(std::map<int,int>::iterator it = m.begin(); it != m.end(); ++it) {
key.push_back(it->first);
value.push_back(it->second);
std::cout << "Key: " << it->first << std::endl();
std::cout << "Value: " << it->second << std::endl();
}
Or even simpler, if you are using Boost:
map<int,int> m;
pair<int,int> me; // what a map<int, int> is made of
vector<int> v;
BOOST_FOREACH(me, m) {
v.push_back(me.first);
cout << me.first << "\n";
}
Personally, I like the BOOST_FOREACH version because there is less typing and it is very explicit about what it is doing.
Cannot find a key of a std::map with customized compare function
Given two elements a
and b
the comparator is used to decide if a
should come before b
. If comp(a,b) == true
then a
comes before b
.
The same element cannot be placed before itself. Though, your comparator requires that, because mycomp(a,a) == true
.
More specifically the comparator must impose a strict weak ordering. The constraints are listed here: https://en.cppreference.com/w/cpp/named_req/Compare
It says:
- For all
a
,comp(a,a)==false
- If
comp(a,b)==true
thencomp(b,a)==false
- if
comp(a,b)==true
andcomp(b,c)==true
thencomp(a,c)==true
Your comparator violates the first two. Note that the comparator and sorting do not care at all about equality. Certainly a==a
, but even if this was not the case (because your elements have some odd operator==
) comp(a,a)
must return false
.
Using a comparator for sort
or for a std::map
that does not adhere to the requirements listed in the page linked above results in undefined behavior.
Related Topics
Return Statement VS Exit() in Main()
Why Can't I Initialize Non-Const Static Member or Static Array in Class
Is There a Replacement For Unistd.H For Windows (Visual C)
Detect If Stdin Is a Terminal or Pipe
How to Use the Qt'S Pimpl Idiom
How to Make a .Lib File When Have a .Dll File and a Header File
Why Can't Variable Names Start With Numbers
Create Random Number Sequence With No Repeats
Selectively Disable Gcc Warnings For Only Part of a Translation Unit
When Can Outer Braces Be Omitted in an Initializer List
Why Do Constant Expressions Have an Exclusion For Undefined Behavior
Is Is_Constexpr Possible in C++11
Why Does Stringstream ≫≫ Change Value of Target on Failure
Opencv Better Detection of Red Color
Fastest Way to Get Ipv4 Address from String
I Don't Want My Excel Add-In to Return an Array (Instead I Need a Udf to Change Other Cells)