Определить, содержит ли map значение для ключа?
каков наилучший способ определить, содержит ли карта STL значение для данного ключа?
#include <map>
using namespace std;
struct Bar
{
int i;
};
int main()
{
map<int, Bar> m;
Bar b = {0};
Bar b1 = {1};
m[0] = b;
m[1] = b1;
//Bar b2 = m[2];
map<int, Bar>::iterator iter = m.find(2);
Bar b3 = iter->second;
}
рассматривая это в отладчике, это выглядит как iter
- это просто данные мусора.
если я раскомментируйте эту строку:
Bar b2 = m[2]
отладчик показывает, что b2
is {i = 0}
. (Я предполагаю, что это означает, что использование неопределенного индекса вернет структуру со всеми пустыми/неинициализированными значениями?)
ни один из этих методов не так велик. Что мне действительно like-Это такой интерфейс:
bool getValue(int key, Bar& out)
{
if (map contains value for key)
{
out = map[key];
return true;
}
return false;
}
существует ли что-то в этом роде?
9 ответов
существует ли что-то в этом роде?
нет. С классом STL map вы используете ::find()
для поиска карты и сравнения возвращенного итератора с std::map::end()
так
map<int,Bar>::iterator it = m.find('2');
Bar b3;
if(it != m.end())
{
//element found;
b3 = it->second;
}
очевидно, вы можете написать свой собственный getValue()
routine если вы хотите (также В C++ нет причин использовать out
), но я подозреваю, что как только вы получите повесить использованием std::map::find()
вы не хотите тратить свое время.
также ваш код немного неправильный:
m.find('2');
будет искать на карте ключевое значение, которое '2'
. IIRC компилятор C++ неявно преобразует "2" в int, что приводит к числовому значению кода ASCII для "2", которое не является тем, что вы хотите.
так как ваш keytype в этом примере является int
вы хотите искать так:m.find(2);
пока карта не является multimap, одним из самых элегантных способов было бы использовать метод count
if (m.count(key))
// key exists
количество будет 1, если элемент действительно присутствует на карте.
он уже существует с find только не в этом точном синтаксисе.
if (m.find(2) == m.end() )
{
// key 2 doesn't exist
}
если вы хотите получить доступ к значению, если он существует, вы можете сделать:
map<int, Bar>::iterator iter = m.find(2);
if (iter != m.end() )
{
// key 2 exists, do something with iter->second (the value)
}
С C++0x и auto синтаксис проще:
auto iter = m.find(2);
if (iter != m.end() )
{
// key 2 exists, do something with iter->second (the value)
}
Я рекомендую вам привыкнуть к нему, а не пытаться придумать новый механизм для его упрощения. Возможно, вы сможете сократить немного кода, но подумайте о стоимости этого. Теперь вы ввели новую функцию, которая знакома людям с C++ не сможет распознать.
если вы хотите реализовать это в любом случае, несмотря на эти предупреждения, то:
template <class Key, class Value, class Comparator, class Alloc>
bool getValue(const std::map<Key, Value, Comparator, Alloc>& my_map, int key, Value& out)
{
typename std::map<Key, Value, Comparator, Alloc>::const_iterator it = my_map.find(key);
if (it != my_map.end() )
{
out = it->second;
return true;
}
return false;
}
Проверьте возвращаемое значение find
против end
.
map<int, Bar>::iterator it = m.find('2');
if ( m.end() != it ) {
// contains
...
}
Я только что заметил, что с C++20, у нас будет
std::map::contains( const Key& key ) const;
это вернет true, если карта содержит элемент с ключом key
.
вы можете создать свою функцию getValue со следующим кодом:
bool getValue(const std::map<int, Bar>& input, int key, Bar& out)
{
std::map<int, Bar>::iterator foundIter = input.find(key);
if (foundIter != input.end())
{
out = foundIter->second;
return true;
}
return false;
}
Если вы хотите определить, есть ли ключ в map или нет, вы можете использовать функцию-член find() или count() map. Функция find, которая используется здесь в Примере, возвращает итератор элементу или map:: end в противном случае. В случае count счетчик возвращает 1, если найден, иначе он возвращает ноль (или иначе).
if(phone.count(key))
{ //key found
}
else
{//key not found
}
for(int i=0;i<v.size();i++){
phoneMap::iterator itr=phone.find(v[i]);//I have used a vector in this example to check through map you cal receive a value using at() e.g: map.at(key);
if(itr!=phone.end())
cout<<v[i]<<"="<<itr->second<<endl;
else
cout<<"Not found"<<endl;
}
Boost multindex можно использовать для правильного решения. Следующее решение не очень лучший вариант, но может быть полезно в нескольких случаях, когда пользователь назначает значение по умолчанию, как 0 или NULL при инициализации и хотите проверить, если значение было изменено.
Ex.
< int , string >
< string , int >
< string , string >
consider < string , string >
mymap["1st"]="first";
mymap["second"]="";
for (std::map<string,string>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
{
if ( it->second =="" )
continue;
}