它是可能的,在PHP中,在不使用递归或引用的情况下扁平化(bi/multi)维数组?
我只对值感兴趣,所以键可以忽略,我认为在array_map()和array_values()的行。
它是可能的,在PHP中,在不使用递归或引用的情况下扁平化(bi/multi)维数组?
我只对值感兴趣,所以键可以忽略,我认为在array_map()和array_values()的行。
当前回答
从PHP v7.4开始,可以使用展开操作符并合并数组。简单有效。
$flatArr = array_merge(...$originalArray);
其他回答
非递归,非基于引用的实现,这可能比基于递归的实现更容易理解。 可以管理任意深度多维数组,不能平化关联数组。 它的工作原理是每个周期将数组压平一层,直到它完全有效。
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>
如果你有一个对象数组,想用一个节点把它压平,只需要使用这个函数:
function objectArray_flatten($array,$childField) {
$result = array();
foreach ($array as $node)
{
$result[] = $node;
if(isset($node->$childField))
{
$result = array_merge(
$result,
objectArray_flatten($node->$childField,$childField)
);
unset($node->$childField);
}
}
return $result;
}
<?php
//recursive solution
//test array
$nested_array = [[1,2,[3]],4,[5],[[[6,[7=>[7,8,9,10]]]]]];
/*-----------------------------------------
function call and return result to an array
------------------------------------------*/
$index_count = 1;
$flatered_array = array();
$flatered_array = flat_array($nested_array, $index_count);
/*-----------------------------------------
Print Result
-----------------------------------------*/
echo "<pre>";
print_r($flatered_array);
/*-----------------------------------------
function to flaten an array
-----------------------------------------*/
function flat_array($nested_array, & $index_count, & $flatered_array) {
foreach($nested_array AS $key=>$val) {
if(is_array($val)) {
flat_array($val, $index_count, $flatered_array);
}
else {
$flatered_array[$index_count] = $val;
++$index_count;
}
}
return $flatered_array;
}
?>
诀窍是通过引用传递源数组和目标数组。
function flatten_array(&$arr, &$dst) {
if(!isset($dst) || !is_array($dst)) {
$dst = array();
}
if(!is_array($arr)) {
$dst[] = $arr;
} else {
foreach($arr as &$subject) {
flatten_array($subject, $dst);
}
}
}
$recursive = array('1', array('2','3',array('4',array('5','6')),'7',array(array(array('8'),'9'),'10')));
echo "Recursive: \r\n";
print_r($recursive);
$flat = null;
flatten_array($recursive, $flat);
echo "Flat: \r\n";
print_r($flat);
// If you change line 3 to $dst[] = &$arr; , you won't waste memory,
// since all you're doing is copying references, and imploding the array
// into a string will be both memory efficient and fast:)
echo "String:\r\n";
echo implode(',',$flat);