简体   繁体   English

将最大值传播到嵌套树javascript中的父节点

[英]Propagate max value to parent nodes in nested tree javascript

Having a nested array like the following one:有一个像下面这样的嵌套数组:

[
    {
        "id": 100,
        "idParent": null,
        "anidatedView": null,
        "state": null,
        "warningHighThreshold": null,
        "dangerHighThreshold": null,
        "lvl": 1,
        "children": [
            {
                "id": 139,
                "idParent": 100,
                "anidatedView": null,
                "state": null,
                "warningHighThreshold": null,
                "dangerHighThreshold": null,
                "lvl": 2,
                "children": [
                    {
                        "id": 186,
                        "idParent": 139,
                        "anidatedView": 279,
                        "state": 15.58,
                        "warningHighThreshold": 80,
                        "dangerHighThreshold": 100,
                        "lvl": 3,
                        "children": []
                    },
                    {
                        "id": 189,
                        "idParent": 139,
                        "anidatedView": 193,
                        "state": 40.65,
                        "warningHighThreshold": 80,
                        "dangerHighThreshold": 100,
                        "lvl": 3,
                        "children": []
                    }
                ]
            },
            {
                "id": 140,
                "idParent": 100,
                "anidatedView": null,
                "state": null,
                "warningHighThreshold": null,
                "dangerHighThreshold": null,
                "lvl": 2,
                "children": [
                    {
                        "id": 193,
                        "idParent": 140,
                        "anidatedView": 183,
                        "state": 65.41,
                        "warningHighThreshold": 92,
                        "dangerHighThreshold": 100,
                        "lvl": 3,
                        "children": []
                    }
                ]
            },
            {
                "id": 141,
                "idParent": 100,
                "anidatedView": null,
                "state": null,
                "warningHighThreshold": null,
                "dangerHighThreshold": null,
                "lvl": 2,
                "children": [
                    {
                        "id": 194,
                        "idParent": 141,
                        "anidatedView": 143,
                        "state": 60.77,
                        "warningHighThreshold": 90,
                        "dangerHighThreshold": 100,
                        "lvl": 3,
                        "children": []
                    },
                    {
                        "id": 195,
                        "idParent": 141,
                        "anidatedView": 436,
                        "state": 59.13,
                        "warningHighThreshold": 90,
                        "dangerHighThreshold": 100,
                        "lvl": 3,
                        "children": []
                    }
                ]
            }
        ]
    }
]

I´m trying to propagate the max value of state(also warningHighThreshold and dangerHighThreshold of that max node) to all parent nodes.我正在尝试将状态的最大值(还有该最大节点的 warningHighThreshold 和 riskHighThreshold)传播到所有父节点。
State and thresholds values will be always avalable on the last level on the tree.状态和阈值将始终在树的最后一层可用。

Any idea how to do this with recursion?知道如何用递归来做到这一点吗?

Thanks in advance!提前致谢!

I have finally managed to solve the problem.我终于设法解决了这个问题。 I leave my solution for those who may have the same issue.我把我的解决方案留给那些可能有同样问题的人。

const populateState = item => {
  if (item.children.length) {
    const maxValue = item.children
      .map(child => populateState(child))
      .filter(({ state }) => state != null)
      .reduce((maxValue, value) => (value.state > maxValue.state ? value : maxValue), { state: -1 })
    item.state = maxValue.state
    item.warningHighThreshold = maxValue.warningHighThreshold
    item.dangerHighThreshold = maxValue.dangerHighThreshold
    return maxValue
  } else {
    const { state, warningHighThreshold, dangerHighThreshold } = item
    return { state, warningHighThreshold, dangerHighThreshold }
  }
}

Usage:用法:
(The array variable is the list I`ve defined in the question) 数组变量是我在问题中定义的列表)

populateState({ children: array})

Any code enhancement is welcome.欢迎任何代码增强。

Try this:试试这个:

 const list = JSON.parse(`[ { "id": 100, "idParent": null, "anidatedView": null, "state": null, "warningHighThreshold": null, "dangerHighThreshold": null, "lvl": 1, "children": [ { "id": 139, "idParent": 100, "anidatedView": null, "state": null, "warningHighThreshold": null, "dangerHighThreshold": null, "lvl": 2, "children": [ { "id": 186, "idParent": 139, "anidatedView": 279, "state": 15.58, "warningHighThreshold": 80, "dangerHighThreshold": 100, "lvl": 3, "children": [] }, { "id": 189, "idParent": 139, "anidatedView": 193, "state": 40.65, "warningHighThreshold": 80, "dangerHighThreshold": 100, "lvl": 3, "children": [] } ] }, { "id": 140, "idParent": 100, "anidatedView": null, "state": null, "warningHighThreshold": null, "dangerHighThreshold": null, "lvl": 2, "children": [ { "id": 193, "idParent": 140, "anidatedView": 183, "state": 65.41, "warningHighThreshold": 92, "dangerHighThreshold": 100, "lvl": 3, "children": [] } ] }, { "id": 141, "idParent": 100, "anidatedView": null, "state": null, "warningHighThreshold": null, "dangerHighThreshold": null, "lvl": 2, "children": [ { "id": 194, "idParent": 141, "anidatedView": 143, "state": 60.77, "warningHighThreshold": 90, "dangerHighThreshold": 101, "lvl": 3, "children": [] }, { "id": 195, "idParent": 141, "anidatedView": 436, "state": 59.13, "warningHighThreshold": 90, "dangerHighThreshold": 100, "lvl": 3, "children": [] } ] } ] } ]`); function getHigh(obj, prop) { let ret = null; for(let n = 0; n < 2; n++) { for(let i = 0; i < obj.length; i++) { const r = getHigh(obj[i].children, prop); if (r > obj[i][prop]) { obj[i][prop] = r; ret = r; } if (obj[i][prop] > ret) ret = obj[i][prop]; } } return ret; } console.log("warningHighThreshold", getHigh(list, "warningHighThreshold")); console.log(JSON.stringify(list, null, 2)); console.log("dangerHighThreshold", getHigh(list, "dangerHighThreshold")); console.log(JSON.stringify(list, null, 2));

This kind of problem could be solve with depth first search...这种问题可以用深度优先搜索来解决......

 let input = [{ "id": 100, "idParent": null, "anidatedView": null, "state": null, "warningHighThreshold": null, "dangerHighThreshold": null, "lvl": 1, "children": [{ "id": 139, "idParent": 100, "anidatedView": null, "state": null, "warningHighThreshold": null, "dangerHighThreshold": null, "lvl": 2, "children": [{ "id": 186, "idParent": 139, "anidatedView": 279, "state": 15.58, "warningHighThreshold": 80, "dangerHighThreshold": 100, "lvl": 3, "children": [] }, { "id": 189, "idParent": 139, "anidatedView": 193, "state": 40.65, "warningHighThreshold": 80, "dangerHighThreshold": 100, "lvl": 3, "children": [] }] }, { "id": 140, "idParent": 100, "anidatedView": null, "state": null, "warningHighThreshold": null, "dangerHighThreshold": null, "lvl": 2, "children": [{ "id": 193, "idParent": 140, "anidatedView": 183, "state": 65.41, "warningHighThreshold": 92, "dangerHighThreshold": 100, "lvl": 3, "children": [] }] }, { "id": 141, "idParent": 100, "anidatedView": null, "state": null, "warningHighThreshold": null, "dangerHighThreshold": null, "lvl": 2, "children": [{ "id": 194, "idParent": 141, "anidatedView": 143, "state": 60.77, "warningHighThreshold": 90, "dangerHighThreshold": 100, "lvl": 3, "children": [] }, { "id": 195, "idParent": 141, "anidatedView": 436, "state": 59.13, "warningHighThreshold": 90, "dangerHighThreshold": 100, "lvl": 3, "children": [] }] }] }] let keys = ["state", "warningHighThreshold", "dangerHighThreshold"]; function populateState(children) { for (let item of children) Object.assign(item, populateState(item.children)) return children.length ? Object.assign(...keys.map(k => ({ [k]: Math.max(...children.map(o => o[k])) }))) : {} } console.log("Max Threshold:", populateState(input), "\\n\\nInput:", input)

Here is a non-mutating version that seems to do what you want, returning a new object with the maximum values rolled up to their ancestors:这是一个非变异版本,它似乎可以做你想做的事,返回一个最大值汇总到其祖先的新对象:

 const collectMax = (xs) => xs .map (({children, kids = collectMax (children), ...rest}) => ({ ...rest, state: Math.max (rest.state, ... kids .map (k => k .state)), warningHighThreshold: Math .max (rest .warningHighThreshold, ... kids .map (k => k .warningHighThreshold)), dangerHighThreshold: Math .max (rest. dangerHighThreshold, ... kids .map (k => k .dangerHighThreshold)), children: kids })) const list = [{id: 100, idParent: null, anidatedView: null, state: null, warningHighThreshold: null, dangerHighThreshold: null, lvl: 1, children: [{id: 139, idParent: 100, anidatedView: null, state: null, warningHighThreshold: null, dangerHighThreshold: null, lvl: 2, children: [{id: 186, idParent: 139, anidatedView: 279, state: 15.58, warningHighThreshold: 80, dangerHighThreshold: 100, lvl: 3, children: []}, {id: 189, idParent: 139, anidatedView: 193, state: 40.65, warningHighThreshold: 80, dangerHighThreshold: 100, lvl: 3, children: []}]}, {id: 140, idParent: 100, anidatedView: null, state: null, warningHighThreshold: null, dangerHighThreshold: null, lvl: 2, children: [{id: 193, idParent: 140, anidatedView: 183, state: 65.41, warningHighThreshold: 92, dangerHighThreshold: 100, lvl: 3, children: []}]}, {id: 141, idParent: 100, anidatedView: null, state: null, warningHighThreshold: null, dangerHighThreshold: null, lvl: 2, children: [{id: 194, idParent: 141, anidatedView: 143, state: 60.77, warningHighThreshold: 90, dangerHighThreshold: 101, lvl: 3, children: []}, {id: 195, idParent: 141, anidatedView: 436, state: 59.13, warningHighThreshold: 90, dangerHighThreshold: 100, lvl: 3, children: []}]}]}] console .log ( collectMax (list) )
 .as-console-wrapper {max-height: 100% !important; top: 0}

We start by recursively applying the function to the children node, then combine our test value together with the appropriate value from each child, and take the maximum, assigning the current object that maximum for the appropriate property.我们首先将函数递归地应用于children节点,然后将我们的测试值与来自每个子节点的适当值组合在一起,并取最大值,将最大值分配给当前对象以用于适当的属性。

But I think it would be cleaner to pull out a helper function from this:但我认为从中提取辅助函数会更清晰:

const collect = (ps, o, k) => Object.assign (... ps .map (p => ({
  [p]: Math.max (o [p], ... k .map (k => k [p]))
})))

const collectMax = (xs) => xs .map (({children, kids = collectMax (children), ...rest}) => ({
  ... rest,
  ... collect (['state', 'warningHighThreshold', 'dangerHighThreshold'], rest, kids),
  children: kids
}))

This does the same thing but slightly simplifies the code and makes it trivial to add new maximum-valued properties.这做同样的事情,但稍微简化了代码,并使添加新的最大值属性变得微不足道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 返回嵌套树中的匹配节点:Javascript - Return matching nodes in a nested tree: Javascript 如何在JavaScript中删除嵌套对象树中的特定节点 - How to delete particular nodes within a nested object tree in JavaScript 递归遍历二叉树Javascript的所有嵌套子节点 - Recursion to traverse all the nested child nodes of Binary Tree Javascript 如何更改嵌套在节点树中的 object 的属性值? - how to change the property value of an object nested in a tree of nodes? 如何在JavaScript中传播嵌套异步函数的返回值 - How do I propagate a return value from a nested asynchronous function in javascript 如何从 JavaScript 中的 JSON 树获取嵌套的父路径? - How to get nested parent path from a JSON tree in JavaScript? 将 id_parent 添加到 javascript 或 typescript 中的嵌套树数组 - add id_parent to nested tree array in javascript or typescript 父子树适用于嵌套的“ if-else”,但不适用于javascript中的“函数递归” - Parent Child Tree Works with nested 'if-else' but not with 'function recursion' in javascript 导航树中的嵌套子节点从其父节点继承链接标记 - Nested children nodes in navigation tree inherit link tag from their parent node Javascript:将简单的节点数组(带有指向父节点的指针)转换为嵌套的数据结构 - Javascript: Convert a plain array of nodes (with pointers to parent nodes) to a nested data structure
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM