You can have a linear workflow with the array functions.
The following is unreadable:
$output = array_reduce(
array_map(
function($n) { return $n ** 2; }
array_filter($input, function($n) { return $n % 2 == 0; })
),
function($x, $y) { return $x + $y; }
);
To get a more linear workflow, don't reinvent the wheel or introduce new dependencies. Just stick to idiomatic PHP and introduce an intermediary variable:
$output = $input;
$output = array_filter($output, function($n) { return $n % 2 == 0; });
$output = array_map(function($n) { return $n ** 2; }, $output);
$output = array_reduce($output, function($x, $y) { return $x + $y; });
Note that I'm copying $input
to $output
for two reasons:
- Avoid overwriting
$input
(which can be helpful for debugging etc.) - Allows you to freely rearrange all operations on the collection
$output
by simply moving the lines up or down.
This linear workflow also is easier to debug - stepping line-by-line in a debugger will reveal the state of the array after each operation, without having to drill through any call-stacks etc.
In fact I think it wouldn't make sense to have a map & reduce method on the collection itself, because they map to a different type. In Haskell for instance the type of map is
(a -> b) -> [a] -> [b]
: a collection ofa
's is mapped to a collection ofb
's. In PHP you can't specialize a collection easily, but clearly if you'd map an array [User] to an array [string], I would argue a simple free function should do the trick. Same story for reduce.Methods that return a view of the collection (filter, take) could maybe be part of such a collection class.