Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the function signature differ between array_map and array_filter/array_reduce?

array_map asks for the $array input as the last parameter(s). array_filter and array_reduce take $array input as the first parameter. As a contrasting example, when you call map, filter or reduce on an array in JavaScript, the callback function signatures look like

(current, index, array) => {…}

Array.prototype.reduce takes the carryover value as the first parameter, but it is still impossible to mix up the parameters' order in the JavaScript methods.

I know that PHP isn't functionally-oriented, but I'm wondering what the design decisions were leading to the signatures for array_map etc.

Does array_map take an array as the last parameter simply because you can feed as many arrays as you want (variadic)? Does the ability to feed an arbitrary number of arrays through the callback function of array_map outweigh having more uniform function signatures?

EDIT/ Comment:

from Wikipedia, this puts in perspective just how long PHP has been evolving:

'Early PHP was not intended to be a new programming language, and grew organically, with Lerdorf noting in retrospect: "I don’t know how to stop it, there was never any intent to write a programming language […] I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way." A development team began to form and, after months of work and beta testing, officially released PHP/FI 2 in November 1997. The fact that PHP was not originally designed but instead was developed organically has led to inconsistent naming of functions and inconsistent ordering of their parameters. In some cases, the function names were chosen to match the lower-level libraries which PHP was "wrapping", while in some very early versions of PHP the length of the function names was used internally as a hash function, so names were chosen to improve the distribution of hash values.'

like image 833
trad Avatar asked Jun 02 '16 22:06

trad


People also ask

What exactly is the the difference between array_map Array_walk and Array_filter?

The resulting array of array_map has the same length as that of the largest input array; array_walk does not return an array but at the same time it cannot alter the number of elements of original array; array_filter picks only a subset of the elements of the array according to a filtering function.

What is array_map function in PHP?

The array_map() function sends each value of an array to a user-made function, and returns an array with new values, given by the user-made function. Tip: You can assign one array to the function, or as many as you like.

Does array map preserve keys?

The returned array will preserve the keys of the array argument if and only if exactly one array is passed. If more than one array is passed, the returned array will have sequential integer keys.

Is there a map function in PHP?

The Ds\Map::map() function of the Map class in PHP is used to apply a callback function to a Map object. This returns the result of applying the callback function to each value present on the map.


1 Answers

Does array_map take an array as the last parameter simply because you can feed as many arrays as you want (variadic)?

Yes; only the last parameter in a method signature can be variadic.

Does the ability to feed an arbitrary number of arrays through the callback function of array_map outweigh having more uniform function signatures?

Essentially, this is asking if array_map should accept multiple arrays. There are good use cases for allowing for calling array_map with multiple arrays; below is an example from the PHP array_map guide that I've slightly modified:

<?php
function showLanguages($n, $s, $g)
{
    return("The number $n is called $s in Spanish and $g in German.");
}

$a = array(1, 2, 3, 4, 5);
$b = array("uno", "dos", "tres", "cuatro", "cinco");
$c = array("eins", "zwei", "drei", "vier", "funf");

$d = array_map("showLanguages", $a, $b, $c);
print_r($d);

What if array_map were changed to have a multidimensional array as the first argument? While it would technically make the function signatures more uniform, it would actually add some additional problems.

The underlying code would not only have to validate that the first argument is an array, it would have to validate that it's an array of arrays. That would make it essentially be a different kind of parameter than just an array, so it would still be a different method signature than the other array_* methods.

If you really wanted to have the callback as the last argument, you could use a modified function that removes the last element, move it to the first argument, then call array_map on that. You would lose all type-hinting, though, so it'd be harder to use.

/*
 * Accepts a variable number of arrays as the first N arguments, takes a callback as the last argument
 */
function map()
{
    $args = func_get_args();

    $callback = array_pop($args);

    array_unshift($args, $callback);

    return call_user_func_array("array_map", $args);
}
like image 61
Chris Forrence Avatar answered Oct 11 '22 09:10

Chris Forrence