我需要将 2d 数组展平为 1d 数组,而不会在此过程中丢失我的数字二级键。
样本数据:
[
[2015 => '2015'],
[2016 => '2016'],
[2017 => '2017'],
[2018 => '2018'],
[2019 => '2019'],
[2020 => '2020'],
[2021 => '2021'],
[2022 => '2022'],
[2023 => '2023']
]
所需输出:
[
2015 => '2015',
2016 => '2016',
2017 => '2017',
2018 => '2018',
2019 => '2019',
2020 => '2020',
2021 => '2021',
2022 => '2022',
2023 => '2023'
]
是否可以得到这样的输出?
你可以做简单的 foreach 循环:
<?php
$years = array(
array(2015 => '2015'),
array(2016 => '2016'),
array(2017 => '2017'),
array(2018 => '2018'),
array(2019 => '2019'),
array(2020 => '2020'),
array(2021 => '2021'),
array(2022 => '2022'),
array(2023 => '2023')
);
foreach($years as $year) {
$key = key($year);
$value = current($year);
$result[$key] = $value;
}
var_dump($result);
输出:
$result = [
2015 => '2015',
2016 => '2016',
2017 => '2017',
2018 => '2018',
2019 => '2019',
2020 => '2020',
2021 => '2021',
2022 => '2022',
2023 => '2023'
];
$theArray = [
[2020 => '2020'], [2021 => '2021'], [2022 => '2022'], [2023 => '2023'],
[2015 => '2015'], [2016 => '2016'], [2017 => '2017'], [2018 => '2018'], [2019 => '2019']
];
$new = [];
foreach ( $theArray as $a) {
$new[key($a)] = $a[key($a)];
}
ksort($new);
print_r($new);
结果
Array
(
[2015] => 2015
[2016] => 2016
[2017] => 2017
[2018] => 2018
[2019] => 2019
[2020] => 2020
[2021] => 2021
[2022] => 2022
[2023] => 2023
)
当然,转到创建原始数组的代码并修改它以创建你想要的而不是它当前所做的可能会更有效。
我最初用这个规范页面关闭了此页面:如何展平多维数组?咨询版主后,建议重新打开这个要求较窄的问题,而不是澄清另一页上每个答案的行为其中包含该问题的可行和不可行的解决方案的混合体。
这是一个相当全面的可行技术列表:
array_reduce()
将 union 运算符与 PHP7.4 的箭头函数语法一起使用不会在全局范围内生成任何变量。 (演示)
var_export(
array_reduce($array, fn($result, $row) => $result + $row, [])
);
array_reduce()
将 array_replace()
与 PHP7.4 的箭头函数语法一起使用不会在全局范围内生成任何变量。 (演示)
var_export(
array_reduce($array, fn($result, $row) => array_replace($result, $row), [])
);
将数据从递归迭代器方法转换为数组不会在全局范围内生成任何变量。 演示
var_export(
iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)))
);
array_walk()
需要声明一个全局变量,并通过闭包中的引用对其进行修改并调用key()
。 演示
$result = [];
array_walk($years, function($row) use(&$result) { $k = key($row); $result[$k] = $row[$k]; });
var_export($result);
array_walk_recursive()
需要声明一个全局变量,并通过闭包中的引用对其进行修改,而无需调用key()
。 演示
$result = [];
array_walk_recursive($years, function($v, $k) use (&$result) { $result[$k] = $v; });
var_export($result);
嵌套
foreach()
循环在全局范围内生成多个变量,但不调用任何函数。 演示
$result = [];
foreach ($array as $row) {
foreach ($row as $k => $v) {
$result[$k] = $v;
}
}
var_export($result);
还有其他可行的方法,使用手动编写脚本的递归和生成器,但它们在可读性方面不太有吸引力,并且对于此任务来说可能有些过头了(在我看来)。
现在介绍一些不能使用的方法,因为它们会丢失行中的数字关联键。不要将这些扁平化技术用于此问题的数据集/要求。
var_export(array_merge(...$array));
var_export(call_user_func_array('array_merge', $array));
var_export(array_reduce($array, 'array_merge', \[\]));
Laravel 的
Arr::flatten()
方法实现手动编写的递归代码,它返回一个平面索引数组——不适合这种情况。
Ouzo goodies 的
Array::flatten()
方法 使用 array_walk_recursive()
返回一个平面索引数组——不适合这种情况。