它是可能的,在PHP中,在不使用递归或引用的情况下扁平化(bi/multi)维数组?
我只对值感兴趣,所以键可以忽略,我认为在array_map()和array_values()的行。
它是可能的,在PHP中,在不使用递归或引用的情况下扁平化(bi/multi)维数组?
我只对值感兴趣,所以键可以忽略,我认为在array_map()和array_values()的行。
当前回答
非递归,非基于引用的实现,这可能比基于递归的实现更容易理解。 可以管理任意深度多维数组,不能平化关联数组。 它的工作原理是每个周期将数组压平一层,直到它完全有效。
function array_flatten(): array{
$result = func_get_args();
// check all elements of $list are not arrays
$_is_flat = function (array $list): bool {
foreach ($list as $val) {
if (is_array($val)) {
return false;
}
}
return true;
};
do {
$tmp = [];
foreach ($result as $val) {
if (is_array($val)) {
if (!array_is_list($val)) {
throw new \Exception(sprintf("array_flatten can't handle associative arrays: %s", json_encode($val)));
}
$tmp = array_merge($tmp, $val);
} else {
$tmp[] = $val;
}
}
$result = $tmp;
} while (!$_is_flat($result));
return $result;
}
以下是它处理的情况:
assertEquals(array_flatten(1, 2), $expected = [1, 2], 'array_flatten 1a');
assertEquals(array_flatten([1], [2]), $expected = [1, 2], 'array_flatten 1b');
assertEquals(array_flatten([1], [[2], 3]), $expected = [1, 2, 3], 'array_flatten 1c');
assertEquals(array_flatten(1, [2, 3], [4, 5]), $expected = [1, 2, 3, 4, 5], 'array_flatten 2');
assertEquals(array_flatten(2, 3, [4, 5], [6, 7], 8), $expected = [2, 3, 4, 5, 6, 7, 8], 'array_flatten 3');
assertEquals(array_flatten([2, 3, [4, 5], [6, 7], 8]), $expected = [2, 3, 4, 5, 6, 7, 8], 'array_flatten 4');
assertEquals(array_flatten([2, [3, [4, [5]], [6, [7]], 8]]), $expected = [2, 3, 4, 5, 6, 7, 8], 'array_flatten complex');
其他回答
使用递归生成器怎么样?https://ideone.com/d0TXCg
<?php
$array = [
'name' => 'Allen Linatoc',
'profile' => [
'age' => 21,
'favourite_games' => [ 'Call of Duty', 'Titanfall', 'Far Cry' ]
]
];
foreach (iterate($array) as $item) {
var_dump($item);
};
function iterate($array)
{
foreach ($array as $item) {
if (is_array($item)) {
yield from iterate($item);
} else {
yield $item;
}
}
}
这是我的解决方案,使用了一个参考:
function arrayFlatten($array_in, &$array_out){
if(is_array($array_in)){
foreach ($array_in as $element){
arrayFlatten($element, $array_out);
}
}
else{
$array_out[] = $array_in;
}
}
$arr1 = array('1', '2', array(array(array('3'), '4', '5')), array(array('6')));
arrayFlatten($arr1, $arr2);
echo "<pre>";
print_r($arr2);
echo "</pre>";
仅平坦二维数组:
$arr = [1, 2, [3, 4]];
$arr = array_reduce($arr, function ($a, $b) {
return array_merge($a, (array) $b);
}, []);
// Result: [1, 2, 3, 4]
非递归,非基于引用的实现,这可能比基于递归的实现更容易理解。 可以管理任意深度多维数组,不能平化关联数组。 它的工作原理是每个周期将数组压平一层,直到它完全有效。
function array_flatten(): array{
$result = func_get_args();
// check all elements of $list are not arrays
$_is_flat = function (array $list): bool {
foreach ($list as $val) {
if (is_array($val)) {
return false;
}
}
return true;
};
do {
$tmp = [];
foreach ($result as $val) {
if (is_array($val)) {
if (!array_is_list($val)) {
throw new \Exception(sprintf("array_flatten can't handle associative arrays: %s", json_encode($val)));
}
$tmp = array_merge($tmp, $val);
} else {
$tmp[] = $val;
}
}
$result = $tmp;
} while (!$_is_flat($result));
return $result;
}
以下是它处理的情况:
assertEquals(array_flatten(1, 2), $expected = [1, 2], 'array_flatten 1a');
assertEquals(array_flatten([1], [2]), $expected = [1, 2], 'array_flatten 1b');
assertEquals(array_flatten([1], [[2], 3]), $expected = [1, 2, 3], 'array_flatten 1c');
assertEquals(array_flatten(1, [2, 3], [4, 5]), $expected = [1, 2, 3, 4, 5], 'array_flatten 2');
assertEquals(array_flatten(2, 3, [4, 5], [6, 7], 8), $expected = [2, 3, 4, 5, 6, 7, 8], 'array_flatten 3');
assertEquals(array_flatten([2, 3, [4, 5], [6, 7], 8]), $expected = [2, 3, 4, 5, 6, 7, 8], 'array_flatten 4');
assertEquals(array_flatten([2, [3, [4, [5]], [6, [7]], 8]]), $expected = [2, 3, 4, 5, 6, 7, 8], 'array_flatten complex');
使用递归。希望在看到它有多简单的时候,你对递归的恐惧会在你看到它有多简单的时候消失。
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>