PHP遍历函数将单个数组转换为带有子元素的嵌套数组 - 基于父ID
Posted
技术标签:
【中文标题】PHP遍历函数将单个数组转换为带有子元素的嵌套数组 - 基于父ID【英文标题】:PHP Traversing Function to turn single array into nested array with children - based on parent id 【发布时间】:2010-01-19 14:42:41 【问题描述】:我有一个类似这样的数组:
Array
(
Array
(
[ID] => 1
[parentcat_ID] => 0
),
Array
(
[ID] => 2
[parentcat_ID] => 0
),
Array
(
[ID] => 6
[parentcat_ID] => 1
),
Array
(
[ID] => 7
[parentcat_ID] => 1
),
Array
(
[ID] => 8
[parentcat_ID] => 6
),
Array
(
[ID] => 9
[parentcat_ID] => 1
),
Array
(
[ID] => 13
[parentcat_ID] => 7
),
Array
(
[ID] => 14
[parentcat_ID] => 8
)
)
但我需要一个函数来递归地将每个项目放入相关父数组内的“子”数组中。所以它看起来更像这样:
Array
(
Array
(
[ID] => 1
[parentcat_ID] => 0
[children] => Array (
Array
(
[ID] => 6
[parentcat_ID] => 1
[childen] => Array (
Array
(
[ID] => 8
[parentcat_ID] => 6
[children] => Array (
Array
(
[ID] => 14
[parentcat_ID] => 8
)
)
)
)
),
Array
(
[ID] => 7
[parentcat_ID] => 1
[children] => Array(
Array
(
[ID] => 13
[parentcat_ID] => 7
)
)
),
Array
(
[ID] => 9
[parentcat_ID] => 1
)
)
)
Array
(
[ID] => 2
[parentcat_ID] => 0
)
)
我希望这是有道理的!
【问题讨论】:
【参考方案1】:试一试(在 php 5.2 下测试):
$inArray = 数组( 数组('ID' => '1', 'parentcat_ID' => '0'), 数组('ID' => '2', 'parentcat_ID' => '0'), 数组('ID' => '6', 'parentcat_ID' => '1'), 数组('ID' => '7', 'parentcat_ID' => '1'), 数组('ID' => '8', 'parentcat_ID' => '6'), 数组('ID' => '9', 'parentcat_ID' => '1'), 数组('ID' => '13', 'parentcat_ID' => '7'), 数组('ID' => '14','parentcat_ID' => '8'), ); 函数 makeParentChildRelations(&$inArray, &$outArray, $currentParentId = 0) if(!is_array($inArray)) 返回; if(!is_array($outArray)) 返回; foreach($inArray as $key => $tuple) if($tuple['parentcat_ID'] == $currentParentId) $tuple['children'] = array(); makeParentChildRelations($inArray, $tuple['children'], $tuple['ID']); $outArray[] = $元组; $outArray = 数组(); makeParentChildRelations($inArray, $outArray); print_r($outArray);【讨论】:
虽然你的解决方案可以完成这项工作,但它的缺点是它使用递归,这本身并不是必需的。 @fireeyedboy:迭代是人为的,递归是神的。 ;P 开个玩笑。当然还有其他方法。 这是递归非常有用的典型案例。并不是说有必要。【参考方案2】:我最近回答了一个类似的问题。 Here 是。希望它适合您的需求。如果没有,请告诉我,我会根据您的规格进行调整。
编辑 好的,这是调整后的版本,应该可以满足您的需求。
function generateMultiArray( array $flatArray )
// initiate result array
$multiArray = array();
// iterate $flatArray
foreach( $flatArray as $item )
// for convenience, initiate these vars
$id = $item[ 'ID' ];
$parentId = $item[ 'parentcat_ID' ];
// initiate this item's children array;
$item[ 'children' ] = array();
// if parent doesn't exist yet, initiate it along with an empty 'children' array
if( !isset( $multiArray[ $parentId ] ) )
$multiArray[ $parentId ] = array(
'children' => array()
);
// if this item is initiated already (as being a parent) merge it with the current item
$multiArray[ $id ] = isset( $multiArray[ $id ] ) ? $multiArray[ $id ] + $item : $item;
// add this item to the parents children collection by reference (for efficiency)
$multiArray[ $parentId ][ 'children' ][ $id ] = &$multiArray[ $id ];
return $multiArray;
请注意,此函数还可以将所有项作为结果数组的根项进行访问,并以它们的 ID 作为索引。
因此,要访问具有任意 id n 的项的子项,您可以:
$multiArray = generateMultiArray( $yourFlatArray );
$children = $multiArray[ n ][ 'children' ]; // replace n with the id
编辑 2 忘记为不是父项的项目启动子数组;现在添加。否则在尝试访问它时会导致通知:
$multiArray = generateMultiArray( $yourFlatArray );
$children = $multiArray[ $someIdWithoutChildren ][ 'children' ];
【讨论】:
我有点看到它的发展方向,但调整它会非常方便:) 我知道它是如何工作的,但是它没有将数组“移动”到“子”数组中,而是复制它们(或不取消设置仍处于根级别的项目) @Joel:实际上是在引用它们,而不是重复。我想你可能会喜欢让所有项目仍然可以在根级别访问的额外便利。我自己经常使用它,因为它也使循环更深嵌套项的子项变得容易。 是的,没错,我一定会把它保存在我的 sn-p 存储库中 :) 谢谢。 我知道这很旧,但这个答案对我帮助很大。谢谢。以上是关于PHP遍历函数将单个数组转换为带有子元素的嵌套数组 - 基于父ID的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 XSLT 将单个子 xml 元素转换为 Json 数组