它是可能的,在PHP中,在不使用递归或引用的情况下扁平化(bi/multi)维数组?
我只对值感兴趣,所以键可以忽略,我认为在array_map()和array_values()的行。
它是可能的,在PHP中,在不使用递归或引用的情况下扁平化(bi/multi)维数组?
我只对值感兴趣,所以键可以忽略,我认为在array_map()和array_values()的行。
当前回答
使用递归。希望在看到它有多简单的时候,你对递归的恐惧会在你看到它有多简单的时候消失。
function flatten($array) {
if (!is_array($array)) {
// nothing to do if it's not an array
return array($array);
}
$result = array();
foreach ($array as $value) {
// explode the sub-array, and add the parts
$result = array_merge($result, flatten($value));
}
return $result;
}
$arr = array('foo', array('nobody', 'expects', array('another', 'level'), 'the', 'Spanish', 'Inquisition'), 'bar');
echo '<ul>';
foreach (flatten($arr) as $value) {
echo '<li>', $value, '</li>';
}
echo '<ul>';
输出:
<ul><li>foo</li><li>nobody</li><li>expects</li><li>another</li><li>level</li><li>the</li><li>Spanish</li><li>Inquisition</li><li>bar</li><ul>
其他回答
从PHP v7.4开始,可以使用展开操作符并合并数组。简单有效。
$flatArr = array_merge(...$originalArray);
如果你想保留中间键:
function flattenArray(array &$result, $value, string $key = "")
{
if (!is_array($value)) {
$result[$key] = $value;
return $result;
}
foreach ($value as $subKey => $subArray) {
$newKey = $key !== "" ? $key . "_" . $subKey : $subKey;
flattenArray($result, $subArray, $newKey);
}
return $result;
}
$nestedArray = [
"name" => "John",
"pets" => [
["id" => 1, "name" => "snooop"],
["id" => 2, "name" => "medor"],
],
"job" => ["title" => "developper"],
];
$intermediateResult = [];
$flattened = flattenArray($intermediateResult, $nestedArray);
var_dump($flattened);
这将输出:
array(6) {
["name"]=>
string(4) "John"
["pets_0_id"]=>
int(1)
["pets_0_name"]=>
string(6) "snooop"
["pets_1_id"]=>
int(2)
["pets_1_name"]=>
string(5) "medor"
["job_title"]=>
string(10) "developper"
}
看到https://ideone.com/KXLtzZ stdout
这个版本可以做深层、浅层或特定数量的层:
/**
* @param array|object $array array of mixed values to flatten
* @param int|boolean $level 0:deep, 1:shallow, 2:2 levels, 3...
* @return array
*/
function flatten($array, $level = 0) {
$level = (int) $level;
$result = array();
foreach ($array as $i => $v) {
if (0 <= $level && is_array($v)) {
$v = flatten($v, $level > 1 ? $level - 1 : 0 - $level);
$result = array_merge($result, $v);
} elseif (is_int($i)) {
$result[] = $v;
} else {
$result[$i] = $v;
}
}
return $result;
}
我相信这是最干净的解决方案,不使用任何突变或不熟悉的类。
<?php
function flatten($array)
{
return array_reduce($array, function($acc, $item){
return array_merge($acc, is_array($item) ? flatten($item) : [$item]);
}, []);
}
// usage
$array = [1, 2, [3, 4], [5, [6, 7]], 8, 9, 10];
print_r(flatten($array));
试试下面这个简单的函数:
function _flatten_array($arr) {
while ($arr) {
list($key, $value) = each($arr);
is_array($value) ? $arr = $value : $out[$key] = $value;
unset($arr[$key]);
}
return (array)$out;
}
所以从这里:
array (
'und' =>
array (
'profiles' =>
array (
0 =>
array (
'commerce_customer_address' =>
array (
'und' =>
array (
0 =>
array (
'first_name' => 'First name',
'last_name' => 'Last name',
'thoroughfare' => 'Address 1',
'premise' => 'Address 2',
'locality' => 'Town/City',
'administrative_area' => 'County',
'postal_code' => 'Postcode',
),
),
),
),
),
),
)
你会得到:
array (
'first_name' => 'First name',
'last_name' => 'Last name',
'thoroughfare' => 'Address 1',
'premise' => 'Address 2',
'locality' => 'Town/City',
'administrative_area' => 'County',
'postal_code' => 'Postcode',
)