array_reduce()不能用作PHP的关联数组"reducer"吗?

Pet*_*uss 13 php associative-array mapreduce

我有一个关联数组$assoc,需要在此上下文中将其缩减为字符串

$OUT = "<row";
foreach($assoc as $k=>$v) $OUT.= " $k=\"$v\"";
$OUT.= '/>';
Run Code Online (Sandbox Code Playgroud)

如何以优雅的方式做同样的事情,但使用array_reduce()


array_walk()功能相近的算法(性能较低,易读性较差),

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

丑陋的解决方案array_map()(并再次join()作为减速器):

  $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)) ."/>";
Run Code Online (Sandbox Code Playgroud)

PS:显然PHP array_reduce()不支持关联数组(为什么??).

hek*_*mgl 11

首先,array_reduce()使用关联数组,但您没有机会访问回调函数中的键,只有值.

您可以使用use关键字来访问$result闭包中的引用,如下例所示array_walk().这非常类似于array_reduce():

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

// Inject reference to `$result` into closure scope.
// $result will get initialized on it's first usage.
array_walk($array, function($val, $key) use(&$result) {
    $result .= "$key=\"$val\"";
});
echo $result;
Run Code Online (Sandbox Code Playgroud)

顺便说一下,你的原始foreach解决方案看起来很优雅.只要阵列保持中小尺寸,也不会有明显的性能问题.


小智 10

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

$OUT = join(" ", array_reduce(array_keys($array), function($as, $a) use ($array) {
    $as[] = sprintf('%s="%s"', $a, $array[$a]); return $as;
}, array()));
Run Code Online (Sandbox Code Playgroud)

  • 这个答案缺少其教育解释。 (4认同)

geo*_*org 5

我个人认为foreach没什么问题,但是如果您想要一个表达式,map可以将您的代码段简化为

$OUT = sprintf("<row %s/>",
    join(" ", array_map(
        function($a, $b) { return "$a=\"$b\""; },
        array_keys($assoc),
        array_values($assoc)
)));
Run Code Online (Sandbox Code Playgroud)

另外,由于您正在生成XML,因此最好使用专用工具,例如:

$doc = new SimpleXMLElement("<row/>");
foreach($assoc as $k => $v)
    $doc->addAttribute($k, $v);
echo $doc->asXML();
Run Code Online (Sandbox Code Playgroud)