【问题标题】:Algorithm to find amount of levels in an array of arrays在数组数组中查找级别数量的算法
【发布时间】:2015-02-07 13:51:26
【问题描述】:

我正在研究一种算法来计算数组中的级别数量。

我需要这个的原因是因为我需要从数据库中获取属于类别父级的类别列表,并且根据该数组具有的级别数量,我需要显示一定数量的类别列表(到选择类别)。

所以这将是每个类别级别的类别列表,例如

Vehicles
        Cars
            honda
                   Red
                   Blue
                   Yellow
            ford
                   Red
            suzuki
                   Red
                   Green
            BMW
        Motorcycles
            bla bla 
                 bla bla 
Groceries
        Fruits
            Berries
                    Red
                        Strawberries

所以我需要一个函数来检查所选父级的级别数量,例如,如果我传递车辆的 ID,如果我们将车辆计为级别 0,我希望它返回 4 或 3,所以我知道如果客户从第一个列表中选择了 Vechicles 我将不得不再显示 3 个列表。

到目前为止,我没有工作的是

function count_children_level($list_of_children, $start_depth = 0){    

    // if the data being passed is an array
    if(is_array($list_of_children)){

        // amount of nodes is equal to the 
        $max = $start_depth;

        foreach($list_of_children as $i){

            $result = count_children_level($i, $start_depth + 1);

            if ($result > $max){

                $max = $result;
            }
        }
        return $max;
    }
    //if is not array
    else {
        return $start_depth;
    }
}

我真的需要了解它是如何工作的,因为我必须使用像这样的几个函数,所以如果可以的话,请详细解释你的答案。

谢谢

【问题讨论】:

    标签: php arrays algorithm categories


    【解决方案1】:

    嵌套数组的深度等于其中最大数组的深度+1。

    因此,对于您的递归函数,您可以进行实际的递归调用,而不是每次都传递整个数组,而只获取子数组的深度。所以这个函数为一个普通的平面数组返回 1,为每个级别返回 1 个额外的值。

    <?php
    function array_depth($array) {
      // Determine largest sub-array. Start with 0 if there are no arrays at all.
      $max = 0;
      foreach ($array as $item) {
        if (is_array($item)) {
          // Make the recursive call, passing not $array, but the sub-array ($item)
          // to the function again.
          $depth = array_depth($item);
          if ($depth > $max)
            $max = $depth;
        }
      }
      // Depth of this array is the depth of the largest sub-array + 1.
      return $max + 1;
    }
    

    我这样称呼它:

    echo array_depth(
      array('x' => 
        array('y' => 
          array('z'))));  // Returns 3.
    

    【讨论】:

    • 你好 GolezTrol,非常感谢你的回答,你能解释一下吗?
    • 您可以发布您使用的数组并将其添加到您的问题中吗?我会用你的数组检查我的代码并在需要的地方修复它,或者解释出了什么问题。
    • 你是对的,它按预期工作,但我传递的数组可能只有两个级别,问题是我不需要知道数组的深度而是类别的深度,因为什么我从数据库中获取的是一个 1 级数组,它具有在 category_id 和 category_parent 中指定的类别结构,所以它比我想象的要复杂得多
    • 啊,我明白了。好吧,这也可以解决,但是如果您需要帮助,我认为您最好提出一个新问题,否则这个问题将变得一团糟。确保发布你得到的数组结构,以使其清楚。
    【解决方案2】:

    我对@GolezTrol 在their answer 中所说的解释(“嵌套数组的深度等于其中最大数组的深度+1”):

    function array_depth($a)
    {
        // If $a is not an array or it's an empty array then its depth is 1
        if (! is_array($a) || count($a) == 0) {
            return 0;
        }
    
        // Otherwise, add 1 to the maximum depth of the elements it contains
        return 1 + max(array_map('array_depth', $a));
    }
    

    【讨论】:

    • 当项目不是数组时应该return 0;。但除此之外,这段代码运行良好。 :) 检查空数组是一个有趣的补充。是否要将空数组计为额外级别取决于您的定义。
    【解决方案3】:

    RecursiveIteratorIterator 类的另一个解决方案。这样就不需要递归函数了:

    $array = array(
        'Vehicles' => array(
            'Cars' => array(
                'honda' => array(
                    'Red',
                    'Blue',
                    'Yellow',
                )
            )
        )
    );
    
    function getTotalDepth($array) {
        $iterator = new RecursiveIteratorIterator(
            new RecursiveArrayIterator($array)
        );
        $max = 0;
        foreach ($iterator as $element) {
            if (!$iterator->callHasChildren()) {
                $max = max($max, $iterator->getDepth());
            }
        }
        return $max;
    }
    
    echo getTotalDepth($array);
    

    如果你想迭代整个数组也很有帮助:

    $iterator = new RecursiveIteratorIterator(
        new RecursiveArrayIterator($array),
        RecursiveIteratorIterator::SELF_FIRST
    );
    
    foreach ($iterator as $element) {
        print_r($element);
        echo '<br>';
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-04
      • 2018-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多