数组从下到上获得所有孩子的总和

时间:2017-06-12 13:39:35

标签: arrays algorithm sum hierarchical-data

我有一个javascript数组,如下所示:

[
    {
        used : 24000,
        service : service A,
        parent : service B,
    },
    {
        used : 450,
        service : service B,
        parent : service C,
    },
    ...
]

我想迭代数组以获得每个服务子项的总和。例如,如果服务将A和B作为子项,那么其used属性将是其自己使用的+他使用的子项的总和。 因此,我需要首先在层次结构中获得最深层次的服务。

然后最终输出可能是:

[
    {
        used : 24000,
        service : service A,
        parent : service B,
    },
    {
        used : 24450, //Sum here has changed
        service : service B,
        parent : service C,
    },
    ...
]

最后一件事,顶级服务并不总是有一个空父...

如果需要,我可以将数组转换为分层数组

有没有人有一个好的算法可以做这样的事情(可能在javascript中,但伪代码也很酷)?

2 个答案:

答案 0 :(得分:2)

您可以使用mapreducefilter来完成以下几行:



var services = [{
        used : 24000,
        service : "A",
        parent : "B",
    }, {
        used : 450,
        service : "B",
        parent : "C",
    }, {
        used : 150,
        service : "C",
    }, {
        used: 100,
        service: "D"
    }
]

// Update one service, children first
var _update_service_sums = function(service, services) {
    var children = services.filter(s => s.parent === service.service)
    children.forEach(c => _update_service_sums(c, services))
    service.used_sum = service.used + children.map(c => c.used_sum).reduce((a, b) => a + b, 0);
}

// Update all services
var update_service_sums = function(services) {
    var roots = services.filter(s => s.parent === undefined)
    roots.forEach(r => _update_service_sums(r, services))
}

update_service_sums(services)
console.log(services)




我不想更改used的值,以便您可以连续多次调用该函数。

我在这里假设可以有多个根服务,而且它们都没有父服务。如果您希望为其他服务计算used_sum,可以直接致电_update_service_sums(service, services)

答案 1 :(得分:0)

这个问题让我想起了很多依赖建设。在依赖关系构建问题中,您必须根据其依赖关系(必须在它们之前执行的作业)来计划作业。如果您有作业A,B和C,其中A取决于B和C,则必须在A之前安排作业B和C.您的问题似乎不是计划,而是将从属作业中的数字添加到当前作业中。获得总数"使用"从服务A开始,您必须首先计算服务B和C的总计。您的数组是依赖关系图的表示,但您不是计划作业,而是计算已使用的属性。

问题是,如果您的图表不是树,那么您的实现必须非常不同。从你的问题的描述,听起来我们正在处理一棵树。如果我们不是,请在评论中告诉我,我可以更新我的答案。如果您将图形视为依赖树,那么您需要做的就是保证,对于图中的每个节点,在评估之前对其进行评估。这可以通过使用邮政订单遍历http://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/来完成。如果您可以在此依赖关系图上实现后期顺序遍历,则只需将左侧大小和右侧遍历返回的值添加到当前总计,然后返回新的"用户"属于它的父母使用。这是一个计算你的值的O(n)算法。