我有一个数组,其值如下:
$menuArray = [
[
'parent' => 'Basic',
'parentId' => 1,
'child' => 'Birthday',
'childId' => 2,
],
[
'parent' => 'Basic',
'parentId' => 1,
'child' => 'Gender',
'childId' => 3,
],
[
'parent' => 'Geo',
'parentId' => 10,
'child' => 'Current City',
'childId' => 11,
],
[
'parent' => 'Known me',
'parentId' => 5,
'child' => 'My personality',
'childId' => 7,
],
[
'parent' => 'Known me',
'parentId' => 5,
'child' => 'Best life moment',
'childId' => 8,
],
];
我想将这个数组分组为
parent
(或 parentId
),最终结果如下:
[
[
'parent' => 'Basic',
'parentId' => 1,
'child' => ['Birthday', 'Gender'],
],
[
'parent' => 'Geo',
'parentId' => 10,
'child' => ['Current City'],
],
[
'parent' => 'Known me',
'parentId' => 5,
'child' => ['My personality', 'Best life moment'],
],
]
我当前的代码:
$filter = [];
$f = 0;
for ($i = 0; $i < count($menuArray); $i++) {
$c = 0;
for ($b = 0; $b < count($filter); $b++) {
if ($filter[$b]['parent'] == $menuArray[$i]['parent']) {
$c++;
}
}
if ($c == 0) {
$filter[$f]['parent'] = $menuArray[$i]['parent'];
$filter[$f]['parentId'] = $menuArray[$i]['parentId'];
$filter[$f]['child'][] = $menuArray[$i]['child'];
$f++;
}
}
但它不会将后续遇到的父级相关行中的
child
值推送到结果数组中。
尝试:
$filter = array();
foreach ($menuArray as $menu) {
if (!array_key_exists($menu['parent_id'], $filter)) {
$filter[$menu['parent_id']] = array(
'parent' => $menu['parent'],
'parent_id' => $menu['parent_id'],
'child' => array()
);
}
$filter[$menu['parent_id']]['child'][$menu['child_id']] = $menu['child'];
}
这将产生一个像这样的数组:
Array
(
[1] => Array
(
[parent] => Basic
[parentId] => 1
[child] => Array
(
[2] => Birthday
[3] => Gender
)
)
[10] => Array
(
[parent] => Geo
[parentId] => 10
[child] => Array
(
[11] => Current City
)
)
[5] => Array
(
[parent] => Known me
[parentId] => 5
[child] => Array
(
[7] => My personality
[8] => Best life moment
)
)
)
请注意,数组索引与 ID 匹配。你不能用 for 循环来循环它,但你可以正确地
foreach ($filter as $parent_id=>$parent)
。如果你愿意,你可以将我的代码的第 4 行更改为 $filter['key_' . $menu['parent_id']]
以强制使用字符串,并且 for 循环将起作用
下一段代码完全未经测试,并且基于按parentId排序的想法。
$filter = array();
$option = null;
for( $i = 0; $i < count( $menuArray ); $i++ ) {
if( count( $filter ) < 1 || $filter[count($filter)-1]['parentId'] != $menuArray['parentId'] ) {
if( $option != null ) {
$filter[] = $option;
}
$option = array(
"parent" => $menuArray[$i]['parent'],
"parentId" => $menuArray[$i]['parentId'],
"child" => array()
);
}
$option['child'][] = $menuArray[$i]['child'];
}
$filter[] = $option; // one last time, because we left the loop already.
unset( $option ); // we don't need it anymore.
它的作用是为每个家长创建一个
$option
。一旦我们点击下一个 parentId
,我们就会将当前的 $option
添加到 $filter
数组中,并创建一个新的 $option
对象。
所有的孩子都不断地添加到当前的
$option
。
仅迭代输入数组一次。
如果第一次遇到
parentId
,请通过删除 childId
元素来改变行,并将 child
值转换为数组 - 这会将标量值转换为包含该值的单元素数组.
然后将变异行作为关联多维条目推入结果数组中,以便可以确认后续遇到的
parentId
。
如果第一次遇到
parentId
,只需将 child
值推入结果数组中相应的组即可。
代码:(演示)
$result = [];
foreach ($array as $row) {
if (!isset($result[$row['parentId']])) {
unset($row['childId']);
$row['child'] = (array) $row['child'];
$result[$row['parentId']] = $row;
} else {
$result[$row['parentId']]['child'][] = $row['child'];
}
}
var_export(array_values($result));
如果您不想通过函数调用来改变
$row
(的复制值),您可以手动键入所需的结构。 (演示)
// if (...) {
$result[$row['parentId']] = [
'parent' => $row['parent'],
'parentId' => $row['parentId'],
'child' => [$row['child']]
];
// } else...