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',
)
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',
)