PHP – 使用点符号键将multidimensional array转换为二维数组

有很多提示和代码示例用点符号访问PHP数组,但是我想做一些相反的事情。 我想采取像这样的multidimensional array:

$myArray = array( 'key1' => 'value1', 'key2' => array( 'subkey' => 'subkeyval' ), 'key3' => 'value3', 'key4' => array( 'subkey4' => array( 'subsubkey4' => 'subsubkeyval4', 'subsubkey5' => 'subsubkeyval5', ), 'subkey5' => 'subkeyval5' ) ); 

把它变成这个(可能通过一些recursion函数):

 $newArray = array( 'key1' => 'value1', 'key2.subkey' => 'subkeyval', 'key3' => 'value3', 'key4.subkey4.subsubkey4' => 'subsubkeyval4', 'key4.subkey5.subsubkey5' => 'subsubkeyval5', 'key4.subkey5' => 'subkeyval5' ); 

代码

 $ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($myArray)); $result = array(); foreach ($ritit as $leafValue) { $keys = array(); foreach (range(0, $ritit->getDepth()) as $depth) { $keys[] = $ritit->getSubIterator($depth)->key(); } $result[ join('.', $keys) ] = $leafValue; } 

产量

 Array ( [key1] => value1 [key2.subkey] => subkeyval [key3] => value3 [key4.subkey4.subsubkey4] => subsubkeyval4 [key4.subkey4.subsubkey5] => subsubkeyval5 [key4.subkey5] => subkeyval5 ) 

演示: http : //codepad.org/YiygqxTM

我需要走,但如果明天需要解释,请问我。

这将处理任意级别的嵌套:

 <? //PHP 5.4+ $dotFlatten = static function(array $item, $context = '') use (&$dotFlatten){ $retval = []; foreach($item as $key => $value){ if (\is_array($value) === true){ foreach($dotFlatten($value, "$context$key.") as $iKey => $iValue){ $retval[$iKey] = $iValue; } } else { $retval["$context$key"] = $value; } } return $retval; }; var_dump( $dotFlatten( [ 'key1' => 'value1', 'key2' => [ 'subkey' => 'subkeyval', ], 'key3' => 'value3', 'key4' => [ 'subkey4' => [ 'subsubkey4' => 'subsubkeyval4', 'subsubkey5' => 'subsubkeyval5', ], 'subkey5' => 'subkeyval5', ], ] ) ); ?> 

RecursiveIteratorIterator已经有了答案。 但是,这是一个更优化的解决scheme, 避免使用嵌套循环

 $iterator = new RecursiveIteratorIterator( new RecursiveArrayIterator($arr), RecursiveIteratorIterator::SELF_FIRST ); $path = []; $flatArray = []; foreach ($iterator as $key => $value) { $path[$iterator->getDepth()] = $key; if (!is_array($value)) { $flatArray[ implode('.', array_slice($path, 0, $iterator->getDepth() + 1)) ] = $value; } } 

这里有几点需要提出。 注意在这里使用RecursiveIteratorIterator::SELF_FIRST常量。 这是重要的,因为默认的是RecursiveIteratorIterator::LEAVES_ONLY ,它不会让我们访问所有的键。 所以在这个常量集合中,我们从数组的顶层开始深入。 这种方法可以让我们存储键的历史logging,并使用RecursiveIteratorIterator::getDepth方法在丰富的叶子上准备键。

这是一个工作演示。

这是我的一个recursion解决scheme,适用于任何深度的数组:

 function convertArray($arr, $narr = array(), $nkey = '') { foreach ($arr as $key => $value) { if (is_array($value)) { $narr = array_merge($narr, convertArray($value, $narr, $nkey . $key . '.')); } else { $narr[$nkey . $key] = $value; } } return $narr; } 

这可以被称为$newArray = convertArray($myArray)

你可以这样做,但克里斯的答案应该是首选:

 <?php $array = array(); foreach($myArray as $key=>$value){ //1st level if(is_array($value)){ //2nd level foreach($value as $key_b=>$value_b){ //3rd level if(is_array($value_b)){ foreach($value_b as $key_c=>$value_c){ $array[$key.'.'.$key_b.'.'.$key_c]=$value_c; } }else{ $array[$key.'.'.$key_b]=$value_b; } } }else{ $array[$key]=$value; } } print_r($array); /* Array ( [key1] => value1 [key2.subkey] => subkeyval [key3] => value3 [key4.subkey4.subsubkey4] => subsubkeyval4 [key4.subkey4.subsubkey5] => subsubkeyval5 [key4.subkey5] => subkeyval5 ) */ 

这个与上面的Blafrat类似的另一种方法 – 只是将数组作为值来处理。

  function dot_flatten($input_arr, $return_arr = array(), $prev_key = '') { foreach ($input_arr as $key => $value) { $new_key = $prev_key . $key; // check if it's associative array 99% good if (is_array($value) && key($value) !==0 && key($value) !==null) { $return_arr = array_merge($return_arr, dot_flatten($value, $return_arr, $new_key . '.')); } else { $return_arr[$new_key] = $value; } } return $return_arr; } 

(唯一不能捕捉的情况是你有一个关联的值,但第一个关键是0)

请注意,RecursiveIteratorIterator可能比常规的recursion函数慢。 https://xenforo.com/community/threads/php-spl-why-is-recursiveiteratoriterator-100x-slower-than-recursive-search.57572/

在这种情况下,使用1000次迭代php5.6给出的样本数组,这个代码速度是两倍(recursion= .032 vs interator = .062) – 但是在大多数情况下差异可能是微不足道的。 主要我喜欢recursion,因为我发现迭代器的逻辑对于一个简单的用例来说是不必要的复杂的。