计算嵌套数组树中叶子的数量

时间:2013-06-25 09:11:16

标签: php arrays tree nested

我有一个嵌套的数组树,由具有以下函数的平面数组生成:

function convertToTree(array $flat, $idField = 'id',
                        $parentIdField = 'parentId',
                        $childNodesField = 'childNodes') {
    $indexed = array();
    // first pass - get the array indexed by the primary id  
    foreach ($flat as $row) {
        $indexed[$row[$idField]] = $row;
        $indexed[$row[$idField]][$childNodesField] = array();
    }

    //second pass  
    $root = null;
    foreach ($indexed as $id => $row) {
        $indexed[$row[$parentIdField]][$childNodesField][$id] =& $indexed[$id];
        if (!$row[$parentIdField]) {
            $root = $id;
        }

    }
    return array($root => $indexed[$root]);
}

我需要为我的阵列的每个节点添加一个“NUMBER OF LEAVES”条目。此条目应计算节点的所有子节点的所有叶子:

Array ( 
    [9] => Array ( 
        [id] => 9, 
        [parentId] => null,
        [name] => Item 0, 
        [NUMBER OF LEAVES] => 4,  (corresponding to leaves 100 and 101 + 200 and 201)
        [childNodes] => Array 
            ( 
                [1] => Array ( 
                    [id] => 1, 
                    [parentId] => 9, 
                    [name] => Item 1, 
                    [NUMBER OF LEAVES] => 2,   (corresponding to leaves 100 and 101)
                    [childNodes] => Array ( 
                        [10] => Array ( 
                            [id] => 10, 
                            [parentId] => 1, 
                            [name] => Item 10, 
                            [childNodes] => Array ( 
                                [100] => Array ( 
                                    [id] => 100, 
                                    [parentId] => 10, 
                                    [name] => Item 100, 
                                    [childNodes] => Array ( ) 
                                ) 
                                [101] => Array ( 
                                    [id] => 101, 
                                    [parentId] => 10, 
                                    [name] => Item 101, 
                                    [childNodes] => Array ( ) 
                                ) 
                            ) 
                        ) 
                    ) 
                ) 
                [2] => Array ( 
                    [id] => 2, 
                    [parentId] => 9, 
                    [name] => Item 2, 
                    [NUMBER OF LEAVES] => 2,   (corresponding to leaves 200 and 201)
                    [childNodes] => Array ( 
                        [20] => Array ( 
                            [id] => 20, 
                            [parentId] => 2, 
                            [name] => Item 20, 
                            [childNodes] => Array ( 
                                [200] => Array ( 
                                    [id] => 200, 
                                    [parentId] => 20, 
                                    [name] => Item 200, 
                                    [childNodes] => Array ( ) 
                                ) 
                                [201] => Array ( 
                                    [id] => 201, 
                                    [parentId] => 20, 
                                    [name] => Item 201, 
                                    [childNodes] => Array ( ) 
                                ) 
                            ) 
                        ) 
                    ) 
                ) 
            ) 
    ) 
)

5 个答案:

答案 0 :(得分:4)

这可以解决你的问题"叶数和#34;对于我的数组的每个节点。此条目应计算节点"

的所有子节点的所有叶子

来自php manual         `$ food = array(' fruits' =>数组(' orange',' banana',' apple'),               '素食' =>阵列('胡萝卜','衣领','豌豆'));

     // recursive count
     echo count($food, COUNT_RECURSIVE); // output 8

     // normal count
     echo count($food); // output 2`

答案 1 :(得分:3)

你可以轻松地做到:

$leaves = 0;
array_walk_recursive($yourArray, function ($leaves) use (&$leaves) {
  $leaves++;
});

示例:

$foods = array(
  'fruits' => array('orange', 'banana', 'apple'),
  'veggie' => array('carrot', 'collard', 'pea')
);

$leaves = 0;
array_walk_recursive($foods, function ($leaves) use (&$leaves) {
  $leaves++;
});
echo $leaves; // will output 6

答案 2 :(得分:1)

解决此问题的方法是使用array_walk_recursive

示例:

new LeaveCounter();

class LeaveCounter
  {
  public function __construct()
    {
    $this->sweet = array('a' => 'apple', 'b' => 'banana');
    $this->fruits = array('sweet' => $this->sweet, 'sour' => 'lemon');

    $this->leaves = 0;

    array_walk_recursive($this->fruits, 'LeaveCounter::incrementLeaves');

    echo $this->leaves;
    }

  public function incrementLeaves($item, $key)
    {
    $this->leaves += 1;
    }
  }

这会计算苹果,香蕉和柠檬,所以它会返回3.

答案 3 :(得分:1)

具有 2 个级别的数组的特殊情况:

$num = count($array, COUNT_RECURSIVE) - count($array);

答案 4 :(得分:0)

//find Totalaleaves
$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($array),
    RecursiveIteratorIterator::SELF_FIRST
);

$ti = 0;
// NUMBER OF LEAVES keys
$tcount = 0;
// NUMBER OF LEAVES values
foreach ($iterator as $key => $item) {
    if (is_array($item) && $item['NUMBER OF LEAVES'] > 0) {
        $tcount = $tcount + $item['NUMBER OF LEAVES'];
        $ti++;
    }
}

echo "Totalleaveskeys=" . $ti;
echo "Totalleavesvalues=" . $tcount;

此解决方案适用于无限制的嵌套多维数组