我有一个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中,但伪代码也很酷)?
答案 0 :(得分:2)
您可以使用map
,reduce
和filter
来完成以下几行:
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)算法。