这可能是初学者的问题,但是我已经花了更长的时间阅读文档,而且找不到任何解决方案。我以为我可以对每个维度使用爆破,然后将这些字符串放回一起str_split
以组成新的简单数组。但是我不知道联接模式是否也不在值中,因此在执行完str_split
原始值之后,可能会损坏。
combine($array1, $array2)
多维数组内部是否存在类似于数组的内容?
这可能是初学者的问题,但是我已经花了更长的时间阅读文档,而且找不到任何解决方案。我以为我可以对每个维度使用爆破,然后将这些字符串放回一起str_split
以组成新的简单数组。但是我不知道联接模式是否也不在值中,因此在执行完str_split
原始值之后,可能会损坏。
combine($array1, $array2)
多维数组内部是否存在类似于数组的内容?
Answers:
<?php
$aNonFlat = array(
1,
2,
array(
3,
4,
5,
array(
6,
7
),
8,
9,
),
10,
11
);
$objTmp = (object) array('aFlat' => array());
array_walk_recursive($aNonFlat, create_function('&$v, $k, &$t', '$t->aFlat[] = $v;'), $objTmp);
var_dump($objTmp->aFlat);
/*
array(11) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
[7]=>
int(8)
[8]=>
int(9)
[9]=>
int(10)
[10]=>
int(11)
}
*/
?>
使用PHP 5.5.9-1ubuntu4.24(CLI)测试(内置:2018年3月16日12:32:06)
$objTmp
在本例中)是通过引用自动传递的;数组不是。尝试使用匿名函数(php.net/manual/en/functions.anonymous.php)代替create_function
。
This bug has been fixed in SVN.
array_values()
?我完全看不到答案中涉及该功能的任何使用。
$array = your array
$result = call_user_func_array('array_merge', $array);
echo "<pre>";
print_r($result);
参考:http : //php.net/manual/en/function.call-user-func-array.php
这是另一个解决方案(适用于多维数组):
function array_flatten($array) {
$return = array();
foreach ($array as $key => $value) {
if (is_array($value)){ $return = array_merge($return, array_flatten($value));}
else {$return[$key] = $value;}
}
return $return;
}
$array = Your array
$result = array_flatten($array);
echo "<pre>";
print_r($result);
$result = array_merge(...$array);
php.net/manual/en/…–
// $array = your multidimensional array
$flat_array = array();
foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $k=>$v){
$flat_array[$k] = $v;
}
还记录了以下内容:http : //www.phpro.org/examples/Flatten-Array.html
iterator_to_array()
到此答案将不需要foreach
循环。它可能是一个简单的单线函数。(虽然有些长的单行)
如果您专门拥有一个数组,且数组的深度不超过一个级别(我发现这种用例很常见),则可以使用array_merge
splat运算符。
<?php
$notFlat = [[1,2],[3,4]];
$flat = array_merge(...$notFlat);
var_dump($flat);
输出:
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
}
splat运算符有效地将数组数组更改为数组列表作为的参数array_merge
。
$flat = array_merge( array_keys( $notFlat ), ...array_values( $notFlat ) );
在PHP 7中,您可以使用生成器和生成器委托(yield from
)来展平数组:
function array_flatten_iterator (array $array) {
foreach ($array as $value) {
if (is_array($value)) {
yield from array_flatten_iterator($value);
} else {
yield $value;
}
}
}
function array_flatten (array $array) {
return iterator_to_array(array_flatten_iterator($array), false);
}
例:
$array = [
1,
2,
[
3,
4,
5,
[
6,
7
],
8,
9,
],
10,
11,
];
var_dump(array_flatten($array));
function flatten_array($array, $preserve_keys = 0, &$out = array()) {
# Flatten a multidimensional array to one dimension, optionally preserving keys.
#
# $array - the array to flatten
# $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys
# $out - internal use argument for recursion
foreach($array as $key => $child)
if(is_array($child))
$out = flatten_array($child, $preserve_keys, $out);
elseif($preserve_keys + is_string($key) > 1)
$out[$key] = $child;
else
$out[] = $child;
return $out;
}
function array_flatten_recursive($array) {
if (!$array) return false;
$flat = array();
$RII = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($RII as $value) $flat[] = $value;
return $flat;
}
该方法的最大好处是,如果在展平时需要,它可以跟踪递归的深度。
这将输出:
$array = array(
'A' => array('B' => array( 1, 2, 3)),
'C' => array(4, 5)
);
print_r(array_flatten_recursive($array));
#Returns:
Array (
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
在PHP> = 5.3中并且基于Luc M的答案(第一个),您可以使用像这样的闭包
array_walk_recursive($aNonFlat, function(&$v, $k, &$t){$t->aFlat[] = $v;}, $objTmp);
我喜欢这个,因为我不必像使用create_function()那样用引号将函数的代码引起来
objTemp
东西
一种基于chaos提交的先前示例函数的新方法,该方法修复了在多数组中覆盖字符串键的错误:
# Flatten a multidimensional array to one dimension, optionally preserving keys.
# $array - the array to flatten
# $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys
# $out - internal use argument for recursion
function flatten_array($array, $preserve_keys = 2, &$out = array(), &$last_subarray_found)
{
foreach($array as $key => $child)
{
if(is_array($child))
{
$last_subarray_found = $key;
$out = flatten_array($child, $preserve_keys, $out, $last_subarray_found);
}
elseif($preserve_keys + is_string($key) > 1)
{
if ($last_subarray_found)
{
$sfinal_key_value = $last_subarray_found . "_" . $key;
}
else
{
$sfinal_key_value = $key;
}
$out[$sfinal_key_value] = $child;
}
else
{
$out[] = $child;
}
}
return $out;
}
Example:
$newarraytest = array();
$last_subarray_found = "";
$this->flatten_array($array, 2, $newarraytest, $last_subarray_found);
/*consider $mArray as multidimensional array and $sArray as single dimensional array
this code will ignore the parent array
*/
function flatten_array2($mArray) {
$sArray = array();
foreach ($mArray as $row) {
if ( !(is_array($row)) ) {
if($sArray[] = $row){
}
} else {
$sArray = array_merge($sArray,flatten_array2($row));
}
}
return $sArray;
}
如果您对松散数组键没事,可以使用递归闭包作为利用array_values()的回调,将多维数组展平,并确保此回调是array_walk()的参数,如下所示。
<?php
$array = [1,2,3,[5,6,7]];
$nu_array = null;
$callback = function ( $item ) use(&$callback, &$nu_array) {
if (!is_array($item)) {
$nu_array[] = $item;
}
else
if ( is_array( $item ) ) {
foreach( array_values($item) as $v) {
if ( !(is_array($v))) {
$nu_array[] = $v;
}
else
{
$callback( $v );
continue;
}
}
}
};
array_walk($array, $callback);
print_r($nu_array);
前面的示例的一个缺点是,与下面的使用array_walk_recursive()和简化的回调的解决方案相比,它需要编写更多的代码:
<?php
$array = [1,2,3,[5,6,7]];
$nu_array = [];
array_walk_recursive($array, function ( $item ) use(&$nu_array )
{
$nu_array[] = $item;
}
);
print_r($nu_array);
查看实时代码
该示例似乎比上一个示例更好,它隐藏了有关如何从多维数组中提取值的详细信息。当然会发生迭代,但是无论它需要递归还是控制结构,您都只能通过细读array.c来了解。由于函数式编程专注于输入和输出,而不是获得结果的细节,因此可以肯定的是,幕后迭代的发生方式将是令人担忧的,即直到有观点的雇主提出这样的问题为止。
我找到了一种将多级数组转换为一个的简单方法。我使用函数“ http_build_query”将数组转换为url字符串。然后,使用爆炸分割字符串并解码该值。
这是一个样本。
$converted = http_build_query($data);
$rows = explode('&', $converted);
$output = array();
foreach($rows AS $k => $v){
list($kk, $vv) = explode('=', $v);
$output[ urldecode($kk) ] = urldecode($vv);
}
return $output;
对不起,我很抱歉,但提供的答案都没有我直觉上理解的“扁平化多维数组”。即这种情况:
[
'a' => [
'b' => 'value',
]
]
提供的所有解决方案都可以将其压平为 ['value']
,但是会丢失有关键和深度的信息,另外,如果您在其他位置有另一个“ b”键,它将覆盖它们。
我想要得到这样的结果:
[
'a_b' => 'value',
]
array_walk_recursive
不会传递有关当前正在递归的密钥的信息,因此我只是通过普通递归来做到这一点:
function flatten($array, $prefix = '') {
$return = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$return = array_merge($return, flatten($value, $prefix . $key . '_'));
} else {
$return[$prefix . $key] = $value;
}
}
return $return;
}
根据自己的喜好修改$ prefix和'_'分隔符。
游乐场在这里:https : //3v4l.org/0B8hf
您可以使用非标准PHP库(NSPL)中的flatten函数。它适用于数组和任何可迭代的数据结构。
assert([1, 2, 3, 4, 5, 6, 7, 8, 9] === flatten([[1, [2, [3]]], [[[4, 5, 6]]], 7, 8, [9]]));
简单的方法..通过递归查看。
<?php
function flatten_array($simple){
static $outputs=array();
foreach ( $simple as $value)
{
if(is_array($value)){
flatten_array($value);
}
else{
$outputs[]=$value;
}
}
return $outputs;
}
$eg=['s'=>['p','n'=>['t']]];
$out=flatten_array($eg);
print_r($out);
?>
static
要为此任务使用潜在的坏主意?意外的数据保留。如果程序员不知道/不期望这种行为,这肯定会让程序员感到惊讶。 看这个示范。
有人可能会觉得这很有用,我在某个维度上将数组展平时遇到问题,因此我将其称为最后一个维度,例如,如果我有如下数组:
array (
'germany' =>
array (
'cars' =>
array (
'bmw' =>
array (
0 => 'm4',
1 => 'x3',
2 => 'x8',
),
),
),
'france' =>
array (
'cars' =>
array (
'peugeot' =>
array (
0 => '206',
1 => '3008',
2 => '5008',
),
),
),
)
要么:
array (
'earth' =>
array (
'germany' =>
array (
'cars' =>
array (
'bmw' =>
array (
0 => 'm4',
1 => 'x3',
2 => 'x8',
),
),
),
),
'mars' =>
array (
'france' =>
array (
'cars' =>
array (
'peugeot' =>
array (
0 => '206',
1 => '3008',
2 => '5008',
),
),
),
),
)
对于这两个数组,当我调用下面的方法时,都会得到结果:
array (
0 =>
array (
0 => 'm4',
1 => 'x3',
2 => 'x8',
),
1 =>
array (
0 => '206',
1 => '3008',
2 => '5008',
),
)
因此,我将扁平化为应该保持不变的最后一个数组维,可以将以下方法重构为实际上在任何级别上停止:
function flattenAggregatedArray($aggregatedArray) {
$final = $lvls = [];
$counter = 1;
$lvls[$counter] = $aggregatedArray;
$elem = current($aggregatedArray);
while ($elem){
while(is_array($elem)){
$counter++;
$lvls[$counter] = $elem;
$elem = current($elem);
}
$final[] = $lvls[$counter];
$elem = next($lvls[--$counter]);
while ( $elem == null){
if (isset($lvls[$counter-1])){
$elem = next($lvls[--$counter]);
}
else{
return $final;
}
}
}
}
如果您只对某个特定键的值感兴趣,则可能会发现此方法很有用:
function valuelist($array, $array_column) {
$return = array();
foreach($array AS $row){
$return[]=$row[$array_column];
};
return $return;
};
例:
给定$ get_role_action =
array(3) {
[0]=>
array(2) {
["ACTION_CD"]=>
string(12) "ADD_DOCUMENT"
["ACTION_REASON"]=>
NULL
}
[1]=>
array(2) {
["ACTION_CD"]=>
string(13) "LINK_DOCUMENT"
["ACTION_REASON"]=>
NULL
}
[2]=>
array(2) {
["ACTION_CD"]=>
string(15) "UNLINK_DOCUMENT"
["ACTION_REASON"]=>
NULL
}
}
比$variables['role_action_list']=valuelist($get_role_action, 'ACTION_CD');
会导致:
$variables["role_action_list"]=>
array(3) {
[0]=>
string(12) "ADD_DOCUMENT"
[1]=>
string(13) "LINK_DOCUMENT"
[2]=>
string(15) "UNLINK_DOCUMENT"
}
在这里,您可以执行值查询,如下所示:
if( in_array('ADD_DOCUMENT', $variables['role_action_list']) ){
//do something
};
这些都不对我有用...所以必须自己运行。正常工作:
function arrayFlat($arr){
$out = '';
foreach($arr as $key => $value){
if(!is_array($value)){
$out .= $value.',';
}else{
$out .= $key.',';
$out .= arrayFlat($value);
}
}
return trim($out,',');
}
$result = explode(',',arrayFlat($yourArray));
echo '<pre>';
print_r($result);
echo '</pre>';
给定多维数组并将其转换为一维,可以通过取消所有具有数组的值并将其保存到第一维来完成,例如:
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;
}
each()
自php7.2起已弃用。