Как проверить есть ли в map ключ
Перейти к содержимому

Как проверить есть ли в map ключ

  • автор:

Как проверить наличие ключа в Hashmap

Иначе, вы можете просто проверить, что такой ключ существует, если получили значение null :

Foo value = map.get(key); if (value != null) < . >else < // Ключ может быть. if (map.containsKey(key)) < // Ключ присутствует, но значение null >else < // Определенно нет ключа >> 

Отслеживать
ответ дан 19 апр 2016 в 14:48
80.6k 9 9 золотых знаков 78 78 серебряных знаков 134 134 бронзовых знака

    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Определите, существует ли ключ на карте в C++

В этом посте будет обсуждаться, как определить, существует ли ключ в карте на C++.

1. Использование std::map::find

Стандартный способ использования std::map::find функция, которая ищет на карте ключ и возвращает ему итератор, или std::map::end если ключа нет в карте. В следующем примере кода показан вызов этой функции:

std :: map < std :: string , int >map = < std :: string key = "two" ; if ( map . find ( key ) != map . end ( ) ) < std :: cout << "Key found" << std :: endl ; std :: cout << "Key not found" << std :: endl ;

результат:

Key found

2. Использование std::map::count

Другой вариант — использовать std::map::count чтобы получить общее количество элементов на карте с определенным ключом. Если на карте присутствует ключ, счетчик будет ровно 1, поскольку все ключи в контейнере карты уникальны. Если ключ не найден, функция count возвращает ноль.

Как проверить есть ли в map ключ

Карта или std::map представляет контейнер, где каждое значение ассоциировано с определенным ключом. И по этому ключу можно получить элемент. Причем ключи могут иметь только уникальные значения. Примером такого контейнера может служить словарь, где каждому слову сопоставляется его перевод или объяснение. Поэтому такие структуры еще называют словарями.

Стандартная библиотека C++ предоставляет два типа словарей: std::map и std::unordered_map . Эти типы представляют шаблоны, которые типизируются двумя типами. Первый тип — Key задает тип для ключей, а второй тип — Value устанавливает тип для значений.

Тип std::map определен в заголовочном файле . Определение пустого словаря:

#include #include int main() < std::mapproducts; >

Здесь определен словарь products, который будет условно хранить цену товаров. Для ключей будет применяться тип std::string , а для значений — числа типа unsigned (условно в качестве ключа будет выступать название товара, а в качестве значения — его цена).

Обращение к элементам

Для обращения к элементам словаря — получения или изменения их значений, так же, как в массиве или векторе, применяется оператора индексирования [] . Только вместо целочисленных индексов можно использовать ключи любого типа в следующем виде:

map[ключ]=значение

#include #include int main() < std::mapproducts; // установка значений products["bread"] = 30; products["milk"] = 80; products["apple"] = 60; // получение значений std::cout

Здесь определен словарь products, в котором ключами служат строки, а значениями — числа типа unsigned. Поэтому для установки элемента в квадратные скобки передается ключ-строка, а присваивается значение-число:

products["bread"] = 30;

Будем считать, что ключ — название товара, а значение — цена товара. То есть в данном случае элементу с ключом «bread» присваивается значение 30. При этом не важно, что ранее создан пустой словарь, и в нем нет никакого элемента с ключом «bread» — если его нет, то он создается. Если же элемент с данным ключом уже есть, то меняется его значение.

Чтобы получить элемент по определенному ключу, используем тот же синтаксис. Например, поскольку значение элемента — число, то мы можем, обратившись по ключу, получить это число:

unsigned breadPrice = products["bread"];

В выше приведенной программе просто выводим значения элементов на консоль:

bread 30 milk 80 apple 60

Перебор элементов:

Для перебора элементов можно применять цикл for в стиле «for-each»:

#include #include int main() < std::mapproducts; // установка значений products["bread"] = 30; products["milk"] = 80; products["apple"] = 60; for (const auto& [product, price] : products) std::cout

Рассмотрим определение цикла. Каждый элемент словаря фактически представляет объект типа std::pair , который хранит, как ключ, так и значение. В нашем случае это объект std::pair . И с помощью полей first и second данного объекта мы могли бы получить соответственно ключ и значение элемента:

for (const auto& element : products) std::cout 

Но начиная со стандарта С++17 также можно использовать другой синтаксис, который позволяет сразу разложить объект на отдельные части - ключ и значение:

for (const auto& [product, price] : products) std::cout 

В данном случае в product будет помещаться ключ, а в price - значение элемента словаря. В итоге при выполнении программы мы получим следующий консольный вывод:

apple 60 bread 30 milk 80

Обратите внимание, что элементы располагаются в словаре и соответственно выводятся на консоль по возрастанию ключей. Поскольку ключи представляют строки, то они сортируются в алфавитном порядке.

Инициализация элементов

Тот факт, что в словаре элементы представляют тип std::pair, позволяет инициализировать словарь объектами std::pair:

#include #include int main() < std::mapproducts < std::pair, std::pair, std::pair >; >

И даже можно сократить определение:

#include #include int main() < std::mapproducts < , , >; >

Удаление элементов

Как было показано выше, для добавления элемента в словарь достаточно просто установить для некоторого ключа какой-нибудь значение. Для удаления же элементов применяется функция erase() , в которую передается ключ удаляемого элемента:

#include #include int main() < std::mapproducts < , , >; products.erase("milk"); // удаляем элемент с ключом "milk" for (const auto& [product, price] : products) std::cout 

Размер словаря

Для получения количества элементов в словаре применяется функция size() . Также класс map имеет функцию empty() , которая возвращает true , если словарь пуст.

#include #include int main() < std::mapproducts < , , >; std::cout 

Проверка наличия элемента

Чтобы проверить, есть ли в словаре элемент с определенным ключом, применяются функции count() (возвращает 1, если элемент есть, и 0 - если отсутствует) и contains() (возвращает true, если элемент есть, и false - если отсутствует). В обе функции передается ключ элемента:

#include #include int main() < std::mapproducts < std::pair, std::pair, std::pair >; std::cout 

Неупорядоченные словари

Тип std::map определяет словарь, который упорядочиваниет все свои элементы - по умолчанию в порядке возрастания ключей. Если упорядоченность не нужна, можно применять ти std::unordered_map , который в целом предоставляет тот же самый функционал, только не упорядочивает элементы и определен в заголовочном файле

#include #include int main() < std::unordered_mapproducts < std::pair, std::pair, std::pair >; for (const auto& [product, price] : products) std::cout

apple 60 milk 80 bread 30

Итераторы

Стоит отметить, что итераторы типа std::map являеются константными, что не позволяет изменять значения элементов при переборе:

#include #include int main() < std::mapphoneBook < , , >; for(auto iter; iter != phoneBook.end(); iter++) < std::cout first << "\t" second // для получения итераторов также можно использовать функции cbegin и cend for(auto iter; iter != phoneBook.cend(); iter++) < std::cout first << "\t" second >

Как проверить есть ли в map ключ

Здравствуйте, Аноним, Вы писали:

А>Как проверить наличие ключа в мапе?

myMapType::iterator I = myMap.find( myKey ); if ( I != myMap.end()) I->second = myValue;

Re: std::map наличие ключа

От: Аноним
Дата: 22.03.09 17:21
Оценка:

Нужно сделать вроде этого:

if(myMap.find(myKey)== myMap.end())
if(myMap.insert(MyMapType::value_type(myKey, myValue).second) < //inserted > else < //already existed >

Re[2]: std::map наличие ключа

От: A.Lokotkov http://www.linkedin.com/pub/alexander-lokotkov/a/701/625
Дата: 22.03.09 18:56
Оценка:

В смысле, наоборот:

if ( myMap.find( myKey ) == myMap.end() ) myMap[myKey] = myValue;

bloß it hudla
Re[3]: std::map наличие ключа

От: Were
Дата: 22.03.09 19:52
Оценка:

Здравствуйте, A.Lokotkov, Вы писали:

AL>В смысле, наоборот:
AL>

AL>if ( myMap.find( myKey ) == myMap.end() ) AL> myMap[myKey] = myValue; AL>

Re[3]: std::map наличие ключа

От: Vain google.ru
Дата: 22.03.09 22:12
Оценка:

Здравствуйте, A.Lokotkov, Вы писали:

AL>В смысле, наоборот:
AL>

AL>if ( myMap.find( myKey ) == myMap.end() ) AL> myMap[myKey] = myValue; AL>

Так 2 раза будет искать.

[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]

Re[4]: std::map наличие ключа

От: _DAle_
Дата: 23.03.09 00:02
Оценка:

Здравствуйте, Vain, Вы писали:

V>Здравствуйте, A.Lokotkov, Вы писали:

AL>>В смысле, наоборот:
AL>>

AL>>if ( myMap.find( myKey ) == myMap.end() ) AL>> myMap[myKey] = myValue; AL>>

V>Так 2 раза будет искать.

Да, но зато это в отличие от предыдущей версии делает то, что просил автор топика.
Если нужно, чтобы поиск был только один раз то нужно сделать, как уже сказали раньше, вот так:

myMap.insert(make_pair(myKey, myValue));

Re[5]: std::map наличие ключа

От: Vain google.ru
Дата: 23.03.09 02:34
Оценка:

Здравствуйте, _DAle_, Вы писали:

V>>Так 2 раза будет искать.
_DA>Да, но зато это в отличие от предыдущей версии делает то, что просил автор топика.
Что не так с предыдущей

Автор: Were
Дата: 22.03.09

[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]

Re[6]: std::map наличие ключа

От: A.Lokotkov http://www.linkedin.com/pub/alexander-lokotkov/a/701/625
Дата: 23.03.09 03:31
Оценка:

Здравствуйте, Vain, Вы писали:

V>Что не так с предыдущей
Автор: Were
Дата: 22.03.09

По условию топик-стартера вставляем, если ключа в мапе нет. В той версии

Автор: Were
Дата: 22.03.09
bloß it hudla
Re: std::map наличие ключа

От: Bell
Дата: 23.03.09 04:17
Оценка: 5 (3) +2

Здравствуйте, Аноним, Вы писали:

Если нужно просто проверить наличие ключа — то можно так:

if(myMap.count(myKey))

главное преимущество — меньше писанины
Любите книгу — источник знаний (с) М.Горький
Re[2]: std::map наличие ключа

От: IROV..
Дата: 23.03.09 11:20
Оценка:

Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Аноним, Вы писали:

B>Если нужно просто проверить наличие ключа — то можно так:
B>

B>if(myMap.count(myKey)) B>

B>главное преимущество — меньше писанины

главный недостаток, в N раз медленее

я не волшебник, я только учусь!
Re: std::map наличие ключа

От: IROV..
Дата: 23.03.09 11:31
Оценка: 2 (1)

Здравствуйте, Аноним, Вы писали:

А>Как проверить наличие ключа в мапе?
А>Нужно сделать вроде этого:
А>

А>if(!myMap.ExistKey(myKey)) А> < А>myMap[myKey] = myValue; А>> А>

это уже проверит, и вставит.

если нужно "если нету, то вставить".

myMap.insert( std::make_pair( myKey, myValue ) );

если нужно при этом еще и узнать вставило оно или нет то пишем так

bool inserted = myMap.insert( std::make_pair( myKey, myValue ) ).second;

я не волшебник, я только учусь!
Re[2]: std::map наличие ключа

От: A.Lokotkov http://www.linkedin.com/pub/alexander-lokotkov/a/701/625
Дата: 23.03.09 11:44
Оценка:

Здравствуйте, IROV. Вы писали:

IRO>ну вопервых
IRO>myMap[myKey] = myValue;
IRO>это уже проверит, и вставит.

если по заданному ключу до вставки лежит очень нужный объект, то он окажется в космосе. хотя, вероятно, топик-стартер этого в виду не имел.

bloß it hudla
Re[3]: std::map наличие ключа

От: IROV..
Дата: 23.03.09 12:01
Оценка:

Здравствуйте, A.Lokotkov, Вы писали:

AL>Здравствуйте, IROV. Вы писали:

IRO>>ну вопервых
IRO>>myMap[myKey] = myValue;
IRO>>это уже проверит, и вставит.

AL>если по заданному ключу до вставки лежит очень нужный объект, то он окажется в космосе. хотя, вероятно, топик-стартер этого в виду не имел.

да именно, это метод update map

я не волшебник, я только учусь!
Re[3]: std::map наличие ключа

От: Bell
Дата: 23.03.09 12:54
Оценка:

Здравствуйте, IROV. Вы писали:

B>>Если нужно просто проверить наличие ключа — то можно так:
B>>

B>>if(myMap.count(myKey)) B>>

B>>главное преимущество — меньше писанины

IRO>главный недостаток, в N раз медленее
Может быть будут аргументы?

ЗЫ
На всякий случай: В табличке 69 в требованиях к сложности стоит логарифм.

Любите книгу — источник знаний (с) М.Горький
Re[4]: std::map наличие ключа

От: IROV..
Дата: 23.03.09 13:30
Оценка:

Здравствуйте, Bell, Вы писали:

B>Здравствуйте, IROV. Вы писали:

B>>>Если нужно просто проверить наличие ключа — то можно так:
B>>>

B>>>if(myMap.count(myKey)) B>>>

B>>>главное преимущество — меньше писанины

IRO>>главный недостаток, в N раз медленее
B>Может быть будут аргументы?
Гавно, вопрос.

 size_type count(const key_type& _Keyval) const < // count all elements that match _Keyval _Paircc _Ans = equal_range(_Keyval); size_type _Num = 0; _Distance(_Ans.first, _Ans.second, _Num); return (_Num); >

что мы тут видем, equal_range -> два find.

Distance!! может для когото секрет, что итерация у std::map это совсем не константная операция.

я не волшебник, я только учусь!
Re[5]: std::map наличие ключа

От: _DAle_
Дата: 23.03.09 13:37
Оценка:

Здравствуйте, IROV. Вы писали:

IRO>Гавно, вопрос.

IRO>

IRO> size_type count(const key_type& _Keyval) const IRO> < // count all elements that match _Keyval IRO> _Paircc _Ans = equal_range(_Keyval); IRO> size_type _Num = 0; IRO> _Distance(_Ans.first, _Ans.second, _Num); IRO> return (_Num); IRO> > IRO>

IRO>что мы тут видем, equal_range -> два find.

IRO>Distance!! может для когото секрет, что итерация у std::map это совсем не константная операция.

Осталось только сказать, что в мэпе всегда в интервале будет максимум один элемент, и никто не запрещал автора реализовать count для map более эффективно.

Re[6]: std::map наличие ключа

От: _DAle_
Дата: 23.03.09 13:41
Оценка:

Здравствуйте, _DAle_, Вы писали:

_DA>Здравствуйте, IROV. Вы писали:

IRO>>Гавно, вопрос.

IRO>>

IRO>> size_type count(const key_type& _Keyval) const IRO>> < // count all elements that match _Keyval IRO>> _Paircc _Ans = equal_range(_Keyval); IRO>> size_type _Num = 0; IRO>> _Distance(_Ans.first, _Ans.second, _Num); IRO>> return (_Num); IRO>> > IRO>>

IRO>>что мы тут видем, equal_range -> два find.

IRO>>Distance!! может для когото секрет, что итерация у std::map это совсем не константная операция.

_DA>Осталось только сказать, что в мэпе всегда в интервале будет максимум один элемент, и никто не запрещал автора реализовать count для map более эффективно.

В stlport это выглядит так:

size_type count(const _KT& __x) const < return _M_t.find(__x) == _M_t.end() ? 0 : 1; >

Ленивые.. А можно ведь сделать лучше.
Re[7]: std::map наличие ключа

От: IROV..
Дата: 23.03.09 13:47
Оценка:

Здравствуйте, _DAle_, Вы писали:

_DA>Здравствуйте, _DAle_, Вы писали:

_DA>>Здравствуйте, IROV. Вы писали:

IRO>>>Гавно, вопрос.

IRO>>>

IRO>>> size_type count(const key_type& _Keyval) const IRO>>> < // count all elements that match _Keyval IRO>>> _Paircc _Ans = equal_range(_Keyval); IRO>>> size_type _Num = 0; IRO>>> _Distance(_Ans.first, _Ans.second, _Num); IRO>>> return (_Num); IRO>>> > IRO>>>

IRO>>>что мы тут видем, equal_range -> два find.

IRO>>>Distance!! может для когото секрет, что итерация у std::map это совсем не константная операция.

_DA>>Осталось только сказать, что в мэпе всегда в интервале будет максимум один элемент, и никто не запрещал автора реализовать count для map более эффективно.
Одна итерация, так одна от begin -> end ^^

начнем с того что сама функция count вообще както глупо выглядит

_DA>В stlport это выглядит так:
_DA>

_DA>size_type count(const _KT& __x) const < return _M_t.find(__x) == _M_t.end() ? 0 : 1; > _DA>

_DA>Ленивые.. А можно ведь сделать лучше.
наверное в stl от мелких, идет впервую очередь обощеность кода (минимум), и поэтому база для map и для multimap идет одна, а в stlport просто выжимают соки.

в любом случаее лучше count не пользоватся, как по мне в map это рудимент от multimap

я не волшебник, я только учусь!
Re[8]: std::map наличие ключа

От: _DAle_
Дата: 23.03.09 13:55
Оценка:

Здравствуйте, IROV. Вы писали:

IRO>Одна итерация, так одна от begin -> end ^^

Просто в N раз никакого замедления не будет, максимум в 2 из-за ненужного вызова equal_range.

IRO>начнем с того что сама функция count вообще както глупо выглядит

Согласен, но она делает именно то, что часто надо, хоть и в кривой форме.

_DA>>В stlport это выглядит так:
_DA>>

_DA>>size_type count(const _KT& __x) const < return _M_t.find(__x) == _M_t.end() ? 0 : 1; > _DA>>

_DA>>Ленивые.. А можно ведь сделать лучше.
IRO>наверное в stl от мелких, идет впервую очередь обощеность кода (минимум), и поэтому база для map и для multimap идет одна, а в stlport просто выжимают соки.

А кому нужна эта конкретная обобщенность кроме самих разработчиков stl? Мне от stl часто нужна скорость.

IRO>в любом случаее лучше count не пользоватся, как по мне в map это рудимент от multimap

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *