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

问题描述 投票:0回答:6

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

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]);
}

我需要为数组的每个节点添加一个条目“叶子数”。该条目应该计算该节点的所有子节点的所有叶子:

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 ( ) 
                                ) 
                            ) 
                        ) 
                    ) 
                ) 
            ) 
    ) 
)
php arrays tree nested
6个回答
6
投票

这可以解决我的数组的每个节点的“树叶数量”问题。该条目应该计算该节点的所有子节点的所有叶子”

来自 php 手册 `$food = array('水果' => array('橙子', '香蕉', '苹果'), 'veggie' => array('胡萝卜', '羽衣甘蓝', '豌豆'));

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

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

6
投票

您可以轻松做到:

$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

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。


1
投票

具有 2 层的数组的特殊情况:

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

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;

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


0
投票

这是我使用的一个简单函数:

function array_count_leaves(array $array) : int {
    $result = 0 ;
    foreach( $array as $v ) {
        if ( is_array($v) ) $result += array_count_leaves($v) ;
        else $result ++ ;
    }
    return $result ;
}
© www.soinside.com 2019 - 2024. All rights reserved.