我有一个示例2d $tasks
数组,它描述了一个嵌套结构:
Array
(
[14] => Array
(
[Id] => 14
[parentId] => null
[Name] => T1
)
[40] => Array
(
[Id] => 40
[parentId] => null
[Name] => T5
)
[41] => Array
(
[Id] => 41
[parentId] => null
[Name] => T4
)
[22] => Array
(
[Id] => 22
[parentId] => 14
[Name] => T2
)
[43] => Array
(
[Id] => 43
[parentId] => 22
[Name] => T2 child
)
[42] => Array
(
[Id] => 42
[parentId] => 14
[Name] => T3
)
)
使用下面的代码我将其转换为适当的树结构:
$sortedArray = array();
// get first level
foreach($tasks as $k => $v){
if($v['parentId'] == 'null'){
$sortedArray[$k] = $v;
unset($tasks[$k]);
}
}
// sort parents
asort($sortedArray);
function getChildren(array & $a1, array & $a2){
foreach($a1 as $k => $v){
findChildren($v, $a2, $k);
}
}
function findChildren($rec1, array & $a2, $key){
foreach($a2 as $k => $v){
if($rec1['parentId'] == $v['Id']){
$a2[$k]['children'][$rec1['Id']] = $rec1;
unset($tasks[$key]);
} else {
if (isset($v['children'])){
findChildren($rec1, $a2[$k]['children'], $key);
}
}
}
}
findChildren($tasks, $sortedArray);
运行此代码后输出$sortedArray
如下所示:
Array
(
[14] => Array
(
[Id] => 14
[parentId] => null
[Name] => T1
[children] => Array
(
[22] => Array
(
[Id] => 22
[parentId] => 14
[Name] => T2
[children] => Array
(
[43] => Array
(
[Id] => 43
[parentId] => 22
[Name] => T2 child
)
)
)
[42] => Array
(
[Id] => 42
[parentId] => 14
[Name] => T3
)
)
)
[40] => Array
(
[Id] => 40
[parentId] => null
[Name] => T5
)
[41] => Array
(
[Id] => 41
[parentId] => null
[Name] => T4
)
)
问题是,在这个输出数组上调用json_encode之后我得到了当前的状态:
{"14":{"Id":"14","parentId":"null"...
所以所有嵌套数组都插入了索引。我知道我可以使用array_values
修复第一级。但有没有简单的方法为所有级别执行此操作?没有它我最终会把'孩子'不是一个阵列而是一个对我不满意的对象。
答案 0 :(得分:7)
您的帖子中没有代码,但$tasks
是作为关联数组创建的。在您的示例中,您还可以像关联数组一样遍历$tasks
:
foreach($tasks as $k => $v){
...
}
您需要像使用数字数组一样将子项添加到$tasks
;区别在于:
//associative array
$test = array();
$test["43"] = "hello";
$test["40"] = "hello1";
$test["23"] = "hello2";
print_r($test);
//numeric array
$testb = array();
$testb[] = "hello";
$testb[] = "hello1";
$testb[] = "hello2";
print_r($testb);
实例:http://codepad.org/tsOhX88h
使用数字数组,您引用为问题{"14":{"Id":"14","parentId":"null"...
的顶级索引(例如14)不再存在。
作为一个简单的最后一步,使用此代码将项目从关联数组推送到新的数字数组:
$finalArray = array();
foreach ($sortedArray as $key=>$val ){
$finalArray[] = $sortedArray[$key];
}
print_r($finalArray);
实例:http://codepad.org/uSGSr1DC
或者您可以使用array_values
一次性完成:
$finalArray = array();
$finalArray = array_values($sortedArray);
print_r($finalArray);
答案 1 :(得分:1)
你没有包含你的json_encode调用,如果你碰巧这样做......
json_encode(array_values($sortedArray), JSON_FORCE_OBJECT);
然后强制将数字索引放入其中。 不确定这是否会对你有所帮助,但它可能会帮助那些看到同样问题的人。
答案 2 :(得分:0)
好的,所以我能想出这样的东西:
function makeIndexed(array & $arr, array & $par = null){
if(is_null($par)){
$arr = array_values($arr);
} else {
$par['children'] = array_values($arr);
}
for($i=0; $i<count($arr); $i++) {
$temp = @$arr[$i]['children'];
if(isset($temp)) {
makeIndexed($arr[$i]['children'], $arr[$i]);
}
}
}
现在调用makeIndexed($sortedArray);
给了我一个有效的JSON,其中'children'是一个节点数组而不是一个对象。我知道这个代码可能很难看并且缺乏性能,但至少会产生正确的结果。如果有人能创造出更清洁/更短的东西,我很乐意将其标记为正确答案。