4

In C++, say you have a std::map<int,int> - how would you use stl algorithms/libraries to find if there is a key that satisfies a certain predicate, e.g. finding if there is a key that is an odd number. So far I've got:

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

But how do I make sure the parameter in the predicate function is actually the key?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
user11508332
  • 537
  • 1
  • 11
  • 28

3 Answers3

3

You can access the key via element.first like this

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
}
MyClass
  • 322
  • 3
  • 10
2

You can hide the pair-based iterator abstraction when using a range-based for loop with structured bindings. This is generally quite readable, although handling the not-found case adds some noise.

std::optional<int> result;

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

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

Using <algorithm> seems more idiomatic, though. On the other hand, linear traversal of a std::map is non-idiomatic anyhow.

lubgr
  • 37,368
  • 3
  • 66
  • 117
1

Element is a pair, you can access its key with element.first. But to access variable, as an iterator you may use -> instead.

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";
  }
}

Output: 9 18

Eduardo Pascual Aseff
  • 1,149
  • 2
  • 13
  • 26
  • 1
    Do not need to use the map's `operator[]` there, simply init-list all the entries `my_map{{6, 120}, {9,18}, {12, 24}};`. Also don't do [using namespace std;](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – MyClass Aug 02 '20 at 22:29
  • 2
    @MyClass I deleted `using namespace std`, but I think there is nothing wrong with `operator[]`, is just an example – Eduardo Pascual Aseff Aug 02 '20 at 22:33