user
Many programming languages provide convenient ways to look for a known value in a simple list of strings or numbers.  
But what if the elements of the list are themselves compound records/objects/data-structures, and the search condition is more complex than a simple equality test?

Task[edit]

Write a function/method/etc. that can find the first element in a given list matching a given condition.  
It should be as generic and reusable as possible.  
(Of course if your programming language already provides such a feature, you can use that instead of recreating it.)

Then to demonstrate its functionality, create the data structure specified under #Data set, and perform on it the searches specified under #Test cases.

Data set

The data structure to be used contains the names and populations (in millions) of the 10 largest metropolitan areas in Africa, and looks as follows when represented in JSON:

```
[
  { "name": "Lagos",                "population": 21.0  },
  { "name": "Cairo",                "population": 15.2  },
  { "name": "Kinshasa-Brazzaville", "population": 11.3  },
  { "name": "Greater Johannesburg", "population":  7.55 },
  { "name": "Mogadishu",            "population":  5.85 },
  { "name": "Khartoum-Omdurman",    "population":  4.98 },
  { "name": "Dar Es Salaam",        "population":  4.7  },
  { "name": "Alexandria",           "population":  4.58 },
  { "name": "Abidjan",              "population":  4.4  },
  { "name": "Casablanca",           "population":  3.98 }
]

```

However, you shouldn't parse it from JSON, but rather represent it natively in your programming language.

* The top-level data structure should be an **ordered** collection *(i.e. a list, array, vector, or similar)*.
* Each element in this list should be an **associative** collection that maps from keys to values *(i.e. a struct, object, hash map, dictionary, or similar)*.
* Each of them has two entries: One string value with key "name", and one numeric value with key "population".
* You may rely on the list being sorted by population count, as long as you explain this to readers.

If any of that is impossible or unreasonable in your programming language, then feel free to deviate, as long as you explain your reasons in a comment above your solution.

Test cases

| Search | Expected result |
| --- | --- |
| Find the (zero-based) **index** of the first city in the list whose **name is "Dar Es Salaam"** | 6 |
| Find the **name** of the first city in this list whose **population is less than 5 million** | Khartoum-Omdurman |
| Find the **population** of the first city in this list whose **name starts with the letter "A"** | 4.58 |

Guidance

If your programming language supports higher-order programming, then the most elegant way to implement the requested functionality in a generic and reusable way, might be to write a function (maybe called "find\_index" or similar), that takes two arguments:

1. The list to search through.
2. A function/lambda/closure (the so-called "predicate"), which will be applied in turn to each element in the list, and whose boolean return value defines whether that element matches the search requirement.

If this is not the approach which would be most natural or idiomatic in your language, explain why, and show what is.

Related tasks

* Search a list

---
assistant
(formerly Perl 6)

The built-in method .first fulfills the requirements of this task.  
It takes any smart-matcher as a predicate. The :k adverb makes it return the key (i.e. numerical index) instead of the value of the element.

**Works with**: Rakudo version 2016.08

```
my @cities =
  { name => 'Lagos',                population => 21.0  },
  { name => 'Cairo',                population => 15.2  },
  { name => 'Kinshasa-Brazzaville', population => 11.3  },
  { name => 'Greater Johannesburg', population =>  7.55 },
  { name => 'Mogadishu',            population =>  5.85 },
  { name => 'Khartoum-Omdurman',    population =>  4.98 },
  { name => 'Dar Es Salaam',        population =>  4.7  },
  { name => 'Alexandria',           population =>  4.58 },
  { name => 'Abidjan',              population =>  4.4  },
  { name => 'Casablanca',           population =>  3.98 },
;

say @cities.first(*<name> eq 'Dar Es Salaam', :k);
say @cities.first(*<population> < 5).<name>;
say @cities.first(*<name>.match: /^A/).<population>;

```

Output:

```
6
Khartoum-Omdurman
4.58

```