2

The PHP function array_map(...) expects a callback as first parameter (or null for creating an array of arrays) and a variable number of array arguments, e.g.:

$foo => array_map(null, $bar, $buz);

Now I have a case, where I need to pass to array_map(...) a variable number of arrays. I cannot hard-code this, since the arrays for the array_map(...)'s input are generated dynamically.

function performSomeLogicAndGetArgumentsForMyFunction() {
    ...
    return ['bar' => [...], 'buz' => [...]];
}
$foo = array_map(null, performSomeLogicAndGetArgumentsForMyFunction());

It doesn't work this way, since array_map(...) expects a variable number of array and not an array of arrays.

Is there a solution for this? How can I keep the call flexible and pass a variable number of arguments to the array_map(...)? (It also applies to every other variadic function I cannot manipulate.)

automatix
  • 14,018
  • 26
  • 105
  • 230

2 Answers2

0

You're returning an array of arrays, and you want to map over the innermost of those arrays. You can use argument unpacking for this:

function say($n, $m) {
    return "The number $n is called $m in Spanish";
}
function arrays() {
    return [
        [ 1, 2, 3 ],
        [ 'uno', 'dos', 'tres' ],
    ];
}
print_r(
    array_map('say', ...arrays())
);

See it online at 3v4l.org.

Alternatively, you could use call_user_func_array as mentioned in the RFC at a measurable run-time cost:

print_r(
    call_user_func_array(
        'array_map',
        array_merge(array ('say'), arrays())
    )
);

See it online at 3v4l.org.

Either of these patterns can implement variadic forms of common methods. For example, to emulate vsprintf one can use:

sprintf('%s %s', ...['Hello', 'World']);
call_user_func_array('sprintf', array_merge(['%s, %s'], ['Hello', 'World']));
bishop
  • 37,830
  • 11
  • 104
  • 139
-3

As a last resort, use eval

//build you array of array variable names with the dynamic content coming in.
$arrays = ['$foo', '$bar', '$baz'];

$str = implode(', ', $arrays);
eval("\$map = array_map(null, $str);");

print_r($map);

Beware never to send un-sanitized input to eval.

See it working

dlporter98
  • 1,590
  • 1
  • 12
  • 18
  • This is working code that has been tested and it answers the question of having a variable number of unknown arrays to pass to the array_map function. If you down vote at least leave a comment explaining why. – dlporter98 Sep 20 '16 at 17:52
  • FYI, I dv'ed this answer (and voted to delete) because there is no compelling reason to use `eval()` when there is ANY alternative (and there are a few). – mickmackusa Apr 21 '22 at 07:31