Map with keys (Flat map)

There are cases when you would like to create a single list of all your matches. flatMap() is great for it. In other words, it allows you to return one, zero or more elements from your mapping function.

->map(function () {
return $value; // Exactly one element
}
->flatMap(function () {
return [...$values]; // Can be 1, many or even zero elements
}

Making a flat map#

Method flatMap() is basically method map(), from which you can return multiple values.

pattern('\w+')->match('I have 19 trains')->flatMap(function (Detail $detail) {
return [
$detail->text(), strlen($detail)
];
});
['I', 1, 'have', 4, '19', 2, 'trains', 6]

Return types#

flatMap() only accepts an array as its return type. Returning a single element and implicitly creating a one-element array under the hood would break our "Explicity rule".

pattern('\w+')->match("I like trains")->flatMap(function (Detail $detail) {
return $detail; // <- throws InvalidReturnValueException
});

So always remember to return an array.

pattern('\w+')->match("I like trains")->flatMap(function (Detail $detail) {
return [$detail->text()]; // ok
});

Variable callbacks#

You can invoke flatMap() with any valid PHP callable, which accepts one or zero string parameters (just like first() and map()) and returns array.

pattern("[\w']+")->match("I'm 19 years old")->flatMap('str_split');
['I', '\'', 'm', '1', '9', 'y', 'e', 'a', 'r', 's', 'o', 'l', 'd']

The callable passed to flatMap() must return an array. InvalidReturnValueException is thrown, otherwise.

Mapping with keys#

Because flatMap() receives an array from its callback, it's possible to also return an associative array with specified keys:

pattern("\w+")->match("Apples are cool")->flatMap(function (Detail $detail) {
return [$detail->text() => $detail->offset()]; // offset is UTF-8 safe
});
[
'Apples' => 0,
'are' => 7,
'cool' => 11
]
note

Keep in mind, that flatMap() uses array_merge() to flatten the results! So If you use int as a key, or even a string with numeric values (like '19') they will be reindexed by array_merge().

note

Detail.offset() returns offset as a valid UTF-8 sequence, whereas preg::match_all counts them as bytes. To return bytes number with T-Regx as well, use byteOffset().

Duplicate keys#

Duplicate keys are not allowed in PHP arrays, so they'll only appear once in the results.

pattern("\w+")->match("Apples are cool")->flatMap(function (Detail $detail) {
return [
$detail->text() => $detail->offset(), // offset is UTF-8 safe
'subject' => $detail->subject()
];
});
[
'Apples' => 0,
'subject' => "Apples are cool",
'are' => 7,
'cool' => 11
]
Last updated on