它是可能的,在PHP中,在不使用递归或引用的情况下扁平化(bi/multi)维数组?
我只对值感兴趣,所以键可以忽略,我认为在array_map()和array_values()的行。
它是可能的,在PHP中,在不使用递归或引用的情况下扁平化(bi/multi)维数组?
我只对值感兴趣,所以键可以忽略,我认为在array_map()和array_values()的行。
当前回答
这里有一个简单的方法:
$My_Array = array(1,2,array(3,4, array(5,6,7), 8), 9);
function checkArray($value) {
foreach ($value as $var) {
if ( is_array($var) ) {
checkArray($var);
} else {
echo $var;
}
}
}
checkArray($My_Array);
其他回答
使用递归。希望在看到它有多简单的时候,你对递归的恐惧会在你看到它有多简单的时候消失。
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 5.6及以上版本中,你可以使用array_merge将二维数组平直,然后使用…操作符。代码简单明了。
array_merge(...$a);
这也适用于关联数组的集合。
$a = [[10, 20], [30, 40]];
$b = [["x" => "A", "y" => "B"], ["y" => "C", "z" => "D"]];
print_r(array_merge(...$a));
print_r(array_merge(...$b));
Array
(
[0] => 10
[1] => 20
[2] => 30
[3] => 40
)
Array
(
[x] => A
[y] => C
[z] => D
)
在PHP 8.0及以下版本中,当外部数组具有非数字键时,数组解包将不起作用。PHP 8.1支持用字符串键解包数组。要支持8.0及以下版本,应该首先调用array_values。
$c = ["a" => ["x" => "A", "y" => "B"], "b" => ["y" => "C", "z" => "D"]];
print_r(array_merge(...array_values($c)));
Array
(
[x] => A
[y] => C
[z] => D
)
更新:基于@ mohammedgharib的评论(适用于PHP 7.3。X和旧的ref)
如果外层数组为空,这将抛出一个错误,因为调用array_merge时参数为零。可以通过添加一个空数组作为第一个参数来避免这种情况。
array_merge([], ...$a);
我需要用HTML输入格式表示PHP多维数组。
$test = [
'a' => [
'b' => [
'c' => ['a', 'b']
]
],
'b' => 'c',
'c' => [
'd' => 'e'
]
];
$flatten = function ($input, $parent = []) use (&$flatten) {
$return = [];
foreach ($input as $k => $v) {
if (is_array($v)) {
$return = array_merge($return, $flatten($v, array_merge($parent, [$k])));
} else {
if ($parent) {
$key = implode('][', $parent) . '][' . $k . ']';
if (substr_count($key, ']') != substr_count($key, '[')) {
$key = preg_replace('/\]/', '', $key, 1);
}
} else {
$key = $k;
}
$return[$key] = $v;
}
}
return $return;
};
die(var_dump( $flatten($test) ));
array(4) {
["a[b][c][0]"]=>
string(1) "a"
["a[b][c][1]"]=>
string(1) "b"
["b"]=>
string(1) "c"
["c[d]"]=>
string(1) "e"
}
从PHP v7.4开始,可以使用展开操作符并合并数组。简单有效。
$flatArr = array_merge(...$originalArray);
我只是想指出这是一个折叠,所以可以使用array_reduce
array_reduce($my_array, 'array_merge', array());
编辑:注意,这可以组成平任意数量的水平。我们可以通过以下几种方式做到这一点:
// Reduces one level
$concat = function($x) { return array_reduce($x, 'array_merge', array()); };
// We can compose $concat with itself $n times, then apply it to $x
// This can overflow the stack for large $n
$compose = function($f, $g) {
return function($x) use ($f, $g) { return $f($g($x)); };
};
$identity = function($x) { return $x; };
$flattenA = function($n) use ($compose, $identity, $concat) {
return function($x) use ($compose, $identity, $concat, $n) {
return ($n === 0)? $x
: call_user_func(array_reduce(array_fill(0, $n, $concat),
$compose,
$identity),
$x);
};
};
// We can iteratively apply $concat to $x, $n times
$uncurriedFlip = function($f) {
return function($a, $b) use ($f) {
return $f($b, $a);
};
};
$iterate = function($f) use ($uncurriedFlip) {
return function($n) use ($uncurriedFlip, $f) {
return function($x) use ($uncurriedFlip, $f, $n) {
return ($n === 0)? $x
: array_reduce(array_fill(0, $n, $f),
$uncurriedFlip('call_user_func'),
$x);
}; };
};
$flattenB = $iterate($concat);
// Example usage:
$apply = function($f, $x) {
return $f($x);
};
$curriedFlip = function($f) {
return function($a) use ($f) {
return function($b) use ($f, $a) {
return $f($b, $a);
}; };
};
var_dump(
array_map(
call_user_func($curriedFlip($apply),
array(array(array('A', 'B', 'C'),
array('D')),
array(array(),
array('E')))),
array($flattenA(2), $flattenB(2))));
当然,我们也可以使用循环,但这个问题要求的是一个组合子函数,类似于array_map或array_values。