array_reduce() can't work as associative-array "reducer" for PHP?

Peter Krauss picture Peter Krauss · Mar 23, 2015 · Viewed 20.2k times · Source

I have an associative array $assoc, and need to reduce to it to a string, in this context

$OUT = "<row";
foreach($assoc as $k=>$v) $OUT.= " $k=\"$v\"";
$OUT.= '/>';

How to do in an elegant way the same thing, but using array_reduce()


Near the same algorithm (lower performance and lower legibility) with array_walk() function,

 array_walk(  $row, function(&$v,$k){$v=" $k=\"$v\"";}  );
 $OUT.= "\n\t<row". join('',array_values($row)) ."/>";

Ugly solution with array_map() (and again join() as reducer):

  $row2 = array_map( 
    function($a,$b){return array(" $a=\"$b\"",1);},
    array_keys($row),
    array_values($row)
  ); // or  
  $OUT ="<row ". join('',array_column($row2,0)) ."/>";

PS: apparently PHP's array_reduce() not support associative arrays (why??).

Answer

hek2mgl picture hek2mgl · Mar 23, 2015

First, array_reduce() works with associative arrays, but you don't have any chance to access the key in the callback function, only the value.

You could use the use keyword to access the $result by reference in the closure like in the following example with array_walk(). This would be very similar to array_reduce():

$array = array(
    'foo' => 'bar',
    'hello' => 'world'
);

// Inject reference to `$result` into closure scope.
// $result will get initialized on its first usage.
array_walk($array, function($val, $key) use(&$result) {
    $result .= " $key=\"$val\"";
});
echo "<row$result />";

Btw, imo your original foreach solution looks elegant too. Also there will be no significant performance issues as long as the array stays at small to medium size.