PHP-使用点符号键将多维数组转换为二维数组
关于使用点符号访问PHP数组,有很多提示和代码示例,但我想做一些相反的事情。我想采用如下多维数组:PHP-使用点符号键将多维数组转换为二维数组,php,arrays,Php,Arrays,关于使用点符号访问PHP数组,有很多提示和代码示例,但我想做一些相反的事情。我想采用如下多维数组: $myArray = array( 'key1' => 'value1', 'key2' => array( 'subkey' => 'subkeyval' ), 'key3' => 'value3', 'key4' => array( 'subkey4' => array(
$myArray = array(
'key1' => 'value1',
'key2' => array(
'subkey' => 'subkeyval'
),
'key3' => 'value3',
'key4' => array(
'subkey4' => array(
'subsubkey4' => 'subsubkeyval4',
'subsubkey5' => 'subsubkeyval5',
),
'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
)
演示:
我得走了,但如果你明天需要解释,请问我。这将处理任意级别的嵌套:
<? //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',
],
]
)
);
?>
这是我对递归解决方案的看法,它适用于任何深度的数组:
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=convertary($myArray)
这是另一种类似于上面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。)
请注意,递归迭代器可能比常规递归函数慢。
在本例中,使用为1000次迭代php5.6提供的示例数组,该代码的速度是原来的两倍(递归=.032 vs interator=.062)-但在大多数情况下,差异可能是微不足道的。我主要喜欢递归,因为对于这样一个简单的用例,我发现迭代器的逻辑不必要地复杂。已经有了答案。但是这里有一个更为优化的解决方案,可以避免使用嵌套循环:
$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;
}
}
这里有几点需要说明。注意这里使用了递归迭代器::SELF_FIRST
常量。这一点很重要,因为默认值是recursiveiterator::LEAVES_ONLY
,它不允许我们访问所有键。有了这个常数集,我们从数组的顶层开始,再深入。这种方法允许我们存储密钥的历史记录,并在使用该方法时准备密钥
我认为array\u walk\u recursive可能可以帮助我构建新的键,因为它似乎可以通过递归完成很多繁重的工作,但它没有提供数组的所有键。例如,在$myArray上使用array\u walk\u recursive(在PHP文档页面上通过示例函数运行)只会为我提供没有数组值的键。我继续尝试用一些很好的foreach循环编写我自己的递归函数,但是这一天太长了,伤到了我的头。如果我得到它(或更接近它),我将继续进行更新。Laravel有
illighted\Support\Arr::dot(_数组)
要做到这一点,它可以在php artisan tinker
中进行测试。这是一个比我认为的好1000%的答案!我以前根本没有玩过递归迭代器(但现在我会玩),所以我甚至没有想到它。干得好!现在,这个函数的反方向如何?@Petah,请看@rambocoder,什么是“ritit”?我是说这个词。。。thx!-->啊,递归迭代器。。。我喜欢这个。在我看到这个之前,我构建了一个自定义函数。这稍微慢一点,但可以很好地处理无索引数组/子数组。不错!
$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;
}
}