我有一个嵌套数组树,它是通过具有以下函数的平面数组生成的:
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]);
}
我的平面阵列:
$flat = [
['id' => 9, 'parentId' => NULL, 'name' => 'Item 0'],
['id' => 1, 'parentId' => 9, 'name' => 'Item 1'],
['id' => 10, 'parentId' => 1, 'name' => 'Item 10'],
['id' => 100, 'parentId' => 10, 'name' => 'Item 100'],
['id' => 101, 'parentId' => 10, 'name' => 'Item 101'],
['id' => 2, 'parentId' => 9, 'name' => 'Item 2'],
['id' => 20, 'parentId' => 2, 'name' => 'Item 20'],
['id' => 200, 'parentId' => 20, 'name' => 'Item 200'],
['id' => 201, 'parentId' => 20, 'name' => 'Item 201'],
];
我需要为数组的每个节点添加一个条目“叶子数”。此条目应计算该节点的所有子节点的所有 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 ( )
)
)
)
)
)
)
)
)
您可以轻松做到:
$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
这可以解决我的数组的每个节点的“树叶数量”问题。该条目应该计算该节点的所有子节点的所有叶子”
来自 php 手册 `$food = array('水果' => array('橙子', '香蕉', '苹果'), 'veggie' => array('胡萝卜', '羽衣甘蓝', '豌豆'));
// recursive count
echo count($food, COUNT_RECURSIVE); // output 8
// normal count
echo count($food); // output 2`
解决这个问题的方法是使用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。
//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;
此解决方案适用于无限嵌套的多维数组
这是我使用的一个简单函数:
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 ;
}
具有 2 层的数组的特殊情况:
$num = count($array, COUNT_RECURSIVE) - count($array);