0

嘿,我已经尝试解决这个问题大约 3 天了,但无济于事。

我有一个看起来像的二维数组:

$testObject = array(
    array(
        "id"=> 1,
        "parentID"=> 0,
        "insuCount"=> 300,
        "totalInsuCount"=> '',
        "childrenCount" => ''
    ),
    array(
        "id"=> 21,
        "parentID"=> 1,
        "insuCount"=> 136,
        "totalInsuCount"=> '',
        "childrenCount" => ''
    ),
    array(
        "id"=> 52,
        "parentID"=> 21,
        "insuCount"=> 99,
        "totalInsuCount"=> '',
        "childrenCount" => ''
    )
);

该数组有一个孩子/父母,它也有 insuCount、totalInsuCount、childrenCount。我正在尝试将层次结构底部的 issuCount 添加到顶部父级,并将结果设置为 totalInsuCount,

它也会计算嵌套的孩子,就像我的情况下的顶级父母有 2 个孩子一样。

所以基本上我的正确数组应该是这样的:

$testObject = array(
    array(
        "id"=> 1,
        "parentID"=> 0,
        "insuCount"=> 300,
        "totalInsuCount"=> 535,
        "childrenCount" => 2
    ),
    array(
        "id"=> 21,
        "parentID"=> 1,
        "insuCount"=> 136,
        "totalInsuCount"=> 235,
        "childrenCount" => 1
    ),
    array(
        "id"=> 52,
        "parentID"=> 21,
        "insuCount"=> 99,
        "totalInsuCount"=> 300,
        "childrenCount" => 0
    )
);

任何人都知道我会怎么做,我已经做了大约 3 天了,现在不知道怎么做。

先谢谢了。

4

3 回答 3

1

请注意,我已经超越了 PHP。所以下面是简单的代码。

  1. 将任务拆分为待办事项和已完成部分。
  2. 虽然 todos 不为空,但重复:
  3. 在 todos 中搜索一个候选人,该候选人在 todos 中是 noone 的父级。
  4. 如果找到初始化累积字段。检查这是否是某人的父母,并积累。(相当于检查所有,因为在 todo 中它是 noone 的父级。)从 todos 中删除。
  5. 数据错误:如果在非空待办事项中没有找到候选人,则某人是其自己的祖父母。

所以:

$todo = array(); // Array of indices into $testObject.
for ($i = 0; $i < count($testObject); ++$i) {
    $todo[] = $i;
}

while (count($todo) > 0) {
    $didOne = FALSE;
    foreach ($todo as $i) {
        $id = $testObject[$i]["id"];
        $isAtBottom = TRUE;
        foreach ($todo as $j) {
            if ($j != $i && $testObject[$j]["parentID"] == $id) {
                $isAtBottom = FALSE;
                break;
            }
        }
        if ($isAtBottom) {
            $didOne = TRUE;
            $testObject[$i]["totalInsuCount"] = $testObject[$i]["insuCount"];
            $testObject[$i]["childrenCount"] = 0;
            for ($k = 0; $k < count($testObject); ++$k) { // Walk done items
                if ($testObject[$k]["id"] != $id 
                    && $testObject[$k]["parentID"] == $id) {
                    $testObject[$i]["totalInsuCount"] +=
                        $testObject[$k]["totalInsuCount"];
                    ++$testObject[$i]["childrenCount"];
                }
            }
            array_splice($todo, $i, 1);
            //break; // As $todo changed, simply next while
        }
    }
    if (!$didOne) {
        error_log("Cyclic dependency");
    }
}
print("<pre>\n");
print_r($testObject);
print("\n</pre>\n");
于 2013-06-04T17:23:49.287 回答
1

首先,您必须将数组转换为键等于您的 ID 的数组。它将允许您直接通过 ID 访问任何元素:

$testObject = array(
     1 => array(
        "id"=> 1,
        "parentID"=> 0,
        "insuCount"=> 300,
        "totalInsuCount"=> '',
        "childrenCount" => ''
     ),
     21 => array(
        "id"=> 21,
        "parentID"=> 1,
        "insuCount"=> 136,
        "totalInsuCount"=> '',
        "childrenCount" => ''
     ),
     52 => array(
        "id"=> 52,
        "parentID"=> 21,
        "insuCount"=> 99,
        "totalInsuCount"=> '',
        "childrenCount" => ''
     )
);

这很容易实现。所以我会把解决方案留给你。

现在我们可以轻松计算所有父母的计数:

foreach ($testObject as $id => &$data){

    $parentId = $data['parentID'];
    while ($parentId && isset($testObject[$parentId])){
        $parentData = &$testObject[$parentId];

        $parentData["childrenCount"]++;
        $parentData["totalInsuCount"] += $data["insuCount"];

        $parentId = $parentData['parentID'];
    }

    $data["totalInsuCount"] += $data["insuCount"];
}

print_r($testObject);

更新

测试是否有任何子项被计算在内并属于某个根条目:

$totalChildren = 0;
foreach ($testObject as $data){
    //sum all childrens of root elements
    if (!$data['parentID']) $totalChildren += $data["childrenCount"] + 1;
}   

echo 'Children counted: ' .$totalChildren;
echo "<br>";
echo 'Total elements: ' .sizeof($testObject);

我还必须准备初始数组,因为一些条目是自引用的:

$newTestObject = array();
foreach ($testObject as $data){
    if ($data['id'] == $data['parentID']) $data['parentID'] = 0;
    $newTestObject[$data['id']] = $data;
}

$testObject = $newTestObject;
于 2013-06-04T17:16:25.910 回答
0

这有点让我烦恼,我不能只写评论......无论如何。

您的最后一个数组条目对我来说没有意义。计数 = 99 + 0 个子值 = 300?计数应该如何工作?

于 2013-06-04T16:47:06.093 回答