【问题标题】:Get most deeply nested arrays获取嵌套最深的数组
【发布时间】:2017-11-22 15:00:46
【问题描述】:

我有异构嵌套数组(每个都包含标量和数组的混合,也可能包含标量和数组,等等递归)。目标是提取所有具有最大深度的数组。请注意,这并不意味着在任何给定子数组的“底部”(局部最大值)提取数组,而是在所有子数组中的最大深度。

例如:

$testArray= array(
    'test1' => 'SingleValue1',
    'test2' => 'SingleValue2',
    'test3' => array(0,1,2),
    'test4' => array(array(3,4,array(5,6,7)), array(8,9,array(10,11,12)),13,14),
    'test5' => array(15,16,17, array(18,19,20)),
);

在此示例中,任何数组出现的最大深度是 3,并且在该深度有两个数组:

  • array(5,6,7)
  • array(10,11,12)

代码应该找到这两个。 ([18,19,20] 子数组不包括在内,因为虽然它在其分支中处于最大深度,但总体而言处于较小的深度。)

我不知道从哪里开始。我尝试了很多东西:在递归函数等中使用foreach,但最终结果总是什么都没有,所有元素或最后一个迭代元素。如何解决这个问题?不需要完整的解决方案,只需提示从哪里开始即可。

【问题讨论】:

  • 发布您已经尝试过的内容,我们可以帮助调试它
  • 您是否在这个特定的数据集中寻找那些特定的数组?或者这是一个关于能够提取子数组的更深层次的问题吗?
  • 我猜这个数组不是静态的?你怎么知道你需要的是 5 6 7 和 10 11 12?
  • 我知道我需要这些,因为它们在 testArray 中嵌套最深
  • 您可以做的是为最深的嵌套数组的级别设置标志,该数组可以初始化为 0。一旦遍历完所有这些,标志的新值就是嵌套最深的子数组。您必须再次运行迭代,以找到子数组处于标志级别(最深级别)的数组并将其打印出来。

标签: php multidimensional-array nested


【解决方案1】:

Roman 的解决方案似乎有效,但我很难理解这种方法。这是我寻找最深子数组的版本。

请参阅我的内联 cmets 以了解每个步骤的说明。基本上,它检查每个数组的子数组,然后在可能的情况下迭代/递归,并使用level 计数器作为键存储子数组。

我的自定义函数将返回一个数组数组。

代码:(Multidimensional Array Demo) (Flat Array Demo) (Empty Array Demo)

function deepestArrays(array $array, int $level = 0, array &$lowest = []): array
{
    $subarrays = array_filter($array, 'is_array');
    if ($subarrays) { // a deeper level exists
        foreach ($subarrays as $subarray) {
            deepestArrays($subarray, $level + 1, $lowest);  // recurse each subarray
        }
    } else {  // deepest level in branch
        $lowestLevel = key($lowest) ?? $level;  // if lowest array is empty, key will be null, fallback to $level value
        if ($lowestLevel === $level) {
            $lowest[$level][] = $array;  // push the array into the results
        } elseif ($lowestLevel < $level) {
            $lowest = [$level => [$array]]; // overwrite with new lowest array
        }
    }
    return current($lowest);  // return the deepest array
}

var_export(
    deepestArrays($testArray)
);

【讨论】:

    【解决方案2】:

    RecursiveIteratorIterator 类的扩展解决方案:

    $testArray= array(
        'test1' => 'SingleValue1',
        'test2' => 'SingleValue2',
        'test3' => array(0,1,2),
        'test4' => array(array(3,4,array(5,6,7)), array(8,9,array(10,11,12)),13,14),
        'test5' => array(15,16,17, array(18,19,20)),
    );
    
    $it = new \RecursiveArrayIterator($testArray);
    $it = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST);
    $max_depth = 0;
    $items = $deepmost = [];
    
    foreach ($it as $item) {
        $depth = $it->getDepth();        // current subiterator depth
        if ($depth > $max_depth) {       // determining max depth
            $max_depth = $depth;
            $items = [];
        }
        if (is_array($item)) {
            $items[$depth][] = $item;
        }
    }
    
    if ($items) {
        $max_key = max(array_keys($items));  // get max key pointing to the max depth
        $deepmost = $items[$max_key];
        unset($items);
    }
    print_r($deepmost);
    

    输出:

    Array
    (
        [0] => Array
            (
                [0] => 5
                [1] => 6
                [2] => 7
            )
    
        [1] => Array
            (
                [0] => 10
                [1] => 11
                [2] => 12
            )
    )
    

    您可以将此方法包装到一个命名函数中,并使用它来获取 最深 数组。

    享受吧! )

    【讨论】:

    • 我实际上偶然发现了 RecursiveIteratorIterator 类,但其中大部分都没有记录。您的代码完成了这项工作。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-04-02
    • 2019-04-09
    • 2019-04-17
    • 1970-01-01
    • 2012-09-16
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多