Как проверить, содержит ли std :: map ключ, удовлетворяющий предикату - PullRequest
3 голосов
/ 03 августа 2020

В C ++, скажем, у вас есть std::map<int,int> - как бы вы использовали stl алгоритмы / библиотеки, чтобы найти, есть ли key, который удовлетворяет определенному предикату, например, поиск, есть ли key, который нечетное число. Пока что у меня есть:

auto variable = std::find_if(my_map.begin(),my_map.end(), [](const auto& element) -> bool {return element%2 == 1;})
if (variable == my_map.end() .....

Но как мне убедиться, что параметр в функции предиката действительно является ключом?

Ответы [ 3 ]

3 голосов
/ 03 августа 2020

Вы можете получить доступ к ключу через element.first вот так

const auto variable = std::find_if(my_map.begin(), my_map.end(), [](const auto& element) {
      return element.first % 2 == 1; 
   }
);

if (variable != my_map.end()
{
   // found
}
2 голосов
/ 03 августа 2020

Вы можете скрыть абстракцию итератора на основе pair при использовании диапазона l oop со структурированными привязками. Как правило, это вполне читаемо, хотя обработка ненайденного случая добавляет некоторого шума.

std::optional<int> result;

for (const auto& [key, value] : my_map)
   if (key % 2 == 1) {
       result = value; // or key
       break;
   }

if (result)
    /* ... */ ;

Однако использование <algorithm> кажется более идиоматическим c. С другой стороны, линейный обход std::map в любом случае не является идиоматическим c.

1 голос
/ 03 августа 2020

Элемент - это пара, вы можете получить доступ к его ключу с помощью element.first. Но для доступа к variable вместо итератора вы можете использовать ->.

int main(){
  std::map<int,int> my_map;

  my_map[6] = 12;
  my_map[9] = 18;
  my_map[12] = 24;

  auto variable = std::find_if(my_map.begin(),my_map.end(), [](const auto& element) -> bool {return element.first%2 == 1;});
  if (variable != my_map.end()){
    std::cout << variable->first << " " << variable->second << "\n";
  }
}

Вывод: 9 18

...