Skip to main content

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 be counter-intuitive and error-prone.

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

flatMap() accepts only array as its return type.

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 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#

Method toMap() can be used to return a dictionary, based on matched occurrences.

pattern('\w+')->match('Apples are cool')->toMap(function (Detail $detail) {
return [$detail->text() => $detail->offset()];
});
[
'Apples' => 0,
'are' => 7,
'cool' => 11
]

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")->toMap(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