php 奇怪地嵌套了 key/value 数组 - 如何 transform/map 更有用?

php strangely nested key/value array - how to transform/map to be more usable?

Microsoft QnAMaker API 返回一个 JSON key/value 数组 (Metadata),格式如下:

$array = [[
    "name" => "someName1",
    "value" => "someValue1",
],
[
    "name" => "someName2",
    "value" => "someValue2",
],
 ..etc..
];

如何将其转换为以下更有用的格式:

$array = [
    "someName1" => "someValue1",
    "someName2" => "someValue2",
    ..etc..
];

我知道我可以使用循环来完成...有没有办法利用内置函数?

如果循环是唯一的方法,你会怎么写,为什么 (performance/readibility/etc.)?

除了循环之外没有真正的方法,所以只需遍历数组,然后按需要创建一个新数组。

$new_array = [];
foreach($array as $row) {
    $new_array[$row['name']] = $row['value'];
}

print_r($new_array);

您可能可以将几个函数组合在一起来执行您想要的操作,但总的来说,循环可能会更具可读性并且总体上更容易。

这使用 array_map() 的组合来重新映射每个元素,然后 array_merge() 来展平结果...

print_r(array_merge(...array_map(function($data) 
                         { return [ $data['name'] => $data['value']]; }
                       , $array)));

这不是很优雅,如果能看到其他关于此的想法会很有趣。

这给...

Array
(
    [someName1] => someValue1
    [someName2] => someValue2
)

由于我之前的回答是 GrumpyCroutons 的骗局,我想我应该用许多数组函数重写,以达到更好的效果。 (但是不要用这个,做一个简单的foreach就可以了)

<?php
array_walk($array, function($v) use (&$result) {
    $result[array_shift($v)] = array_values($v)[0];
});

var_export($result);

输出:

array (
  'someName1' => 'someValue1',
  'someName2' => 'someValue2',
)

这个有效:

$res = [];
array_walk($array, function(&$e) use(&$res) {
    $res[$e['name']] = $e['value'];
    unset($e); // this line adds side effects and it could be deleted
});
var_dump($res);

输出:

array(2) { 
   ["someName1"]=> string(10) "someValue1" 
   ["someName2"]=> string(10) "someValue2" 
} 

您可以简单地使用 array_reduce:

<?php
$output = array_reduce($array, function($a, $b) {
    $a[$b['name']] = $b['value'];

    return $a;
});

var_export($output);

输出:

array (
    'someName1' => 'someValue1',
    'someName2' => 'someValue2',
)

换班时(非 foreach):

<?php
$c = $array;
while($d = array_shift($c))
    $e[array_shift($d)] = array_shift($d);

var_export($e);

输出:

array (
    'someName1' => 'someValue1',
    'someName2' => 'someValue2',
)

虽然在手册中的评论中建议移动比弹出更昂贵。您可以将上面对 $c 的初始赋值替换为 array_reverse 并将 while-shift 替换为 while-pop.

然而,与 foreach 相比,这两种方法都可能很糟糕,但在这里谁知道谁的乐趣。

如果它看起来像 JSONish,array_column 会有所帮助。只需:

<?php
var_export(array_column($array, 'value', 'name'));

输出:

array (
    'someName1' => 'someValue1',
    'someName2' => 'someValue2',
)