简体   繁体   English

如何总结一个嵌套的Javascript对象数组的所有叶节点?

[英]How to sum up all the leaf nodes of a nested Javascript object array?

Currently I have a nested Javascript Object array that has many leaf nodes with the same name but different values 目前,我有一个嵌套的Javascript对象数组,其中包含许多具有相同名称但值不同的叶节点

{
  "children": [
    {
      "name": "Central",
      "children": [
        {
          "name": "Cellophane `Tape",
          "value": 10.528979999999999
        },
        {
          "name": "Cellophane Tape",
          "value": 10.529
        },
        {
          "name": "File Separator",
          "value": 10.529
        },
        {
          "name": "Hard Cover File",
          "value": 10.529
        },
        {
          "name": "Highlighter",
          "value": 10.529
        },
        {
          "name": "Office Chair",
          "value": 10.529
        },
        {
          "name": "Pencil",
          "value": 10.529
        },
        {
          "name": "Tape Dispenser",
          "value": 10.529
        },
        {
          "name": "File Cabinet",
          "value": 21.058
        },
        {
          "name": "Highlighter",
          "value": 21.058
        },
        {
          "name": "Office Chair",
          "value": 21.058
        },
        {
          "name": "Pencil",
          "value": 21.058
        },
        {
          "name": "Plastic Comb Binding",
          "value": 21.058
        },
        {
          "name": "Tape Dispenser",
          "value": 21.058
        },
        {
          "name": "White Board Markers",
          "value": 21.058
        },
        {
          "name": "File Separator",
          "value": 23.273360000000004
        },
        {
          "name": "Binder",
          "value": 23.2734
        },
        {
          "name": "Cellophane Tape",
          "value": 23.2734
        },
        {
          "name": "File Separator",
          "value": 23.2734
        },
        {
          "name": "Hard Cover File",
          "value": 23.2734
        },
        {
          "name": "Highlighter",
          "value": 23.2734
        },
        {
          "name": "Plastic Comb Binding",
          "value": 23.2734
        },
        {
          "name": "Tape Dispenser",
          "value": 23.2734
        },
        {
          "name": "White Board Markers",
          "value": 23.2734
        },
        {
          "name": "Binder",
          "value": 64.0017
        },
        {
          "name": "Eraser",
          "value": 64.0017
        },
        {
          "name": "File Separator",
          "value": 64.0017
        },
        {
          "name": "Office Chair",
          "value": 64.0017
        },
        {
          "name": "Plastic Comb Binding",
          "value": 64.0017
        },
        {
          "name": "Tape Dispenser",
          "value": 64.0017
        },
        {
          "name": "Binder",
          "value": 64.00174
        },
        {
          "name": "Tape Dispenser",
          "value": 64.00174
        },
        {
          "name": "Binder",
          "value": 67.2899
        },
        {
          "name": "Highlighter",
          "value": 67.2899
        },
        {
          "name": "Office Chair",
          "value": 67.2899
        },
        {
          "name": "Plastic Comb Binding",
          "value": 67.2899
        },
        {
          "name": "Tape Dispenser",
          "value": 67.2899
        },
        {
          "name": "Cellophane Tape",
          "value": 74.2509
        },
        {
          "name": "Office Chair",
          "value": 74.2509
        },
        {
          "name": "Pencil",
          "value": 74.2509
        },
        {
          "name": "Plastic Comb Binding",
          "value": 74.2509
        },
        {
          "name": "White Board Markers",
          "value": 74.2509
        },
        {
          "name": "Cellophane Tape",
          "value": 79.7194
        }
      ]
    }
  ]
}

Therefore, what I would like to do is to traverse to all the leaf nodes of this array, then agregate it ACCORDING to each parent like so, 因此,我想做的是遍历此数组的所有叶节点,然后像这样将其聚合到每个父节点

const agregateDeep = x => {
                  if (Array.isArray(x.children)) {
                      x.children = x.children.map(deep);
                      return x;
                  } else {
                      return {
                          x: x.reduce(function (r, o) {
                              (r[o.name]) ? r[o.name] += o.value : r[o.name] = o.value;
                              return r;
                          })

                      };
                  }
              };

Something like this, but using the reduce function returns a flat array. 像这样,但是使用reduce函数会返回一个平面数组。 If so,then how do I insert this flat array back into my leaf nodes? 如果是这样,那么如何将这个平面数组重新插入到我的叶子节点中?

I was able to retrieve ALL leaf nodes and aggregate it, so my expected output is something like this but I want it to be according to EACH parent. 我能够检索所有叶节点并对其进行聚合,因此我的预期输出是这样的,但我希望它与每个父节点一致。

MY DATA : https://api.myjson.com/bins/gki6c 我的数据https : //api.myjson.com/bins/gki6c

Expected Output : 预期产量:

[
  {
    "name": "Central",
    "children": [
      {
            {"name" : "Cellophane Tape","value":79.7194},
            {"name" : "File Separator","value":64.0017},
            {"name" : "Hard Cover File","value":23.2734},
            {"name" : "Highlighter", "value":67.2899},
            {"name" : "Office Chair","value":74.2509},
            {"name" : "Pencil","value": 74.2509},
            {"name" : "Tape Dispenser","value" : 67.2899},
            {"name" : "File Cabinet","value": 21.058},
            {"name" : "Plastic Comb Binding","value": 74.2509},
            {"name" : "White Board Markers","value": 74.2509},
            {"name" : "Binder","value" : 67.2899},
            {"name" : "Eraser","value": 64.0017}
      }
    ]
  }
]
  1. You can maintain a hash for the name and its leaf nodes found across the object 您可以维护在对象中找到的名称及其叶节点的hash
  2. You can filter the leaf nodes and transform it to what you want, check existence in hash, if found add it there and use that array, otherwise create a new array, push it there and save the array in hash. 您可以过滤叶节点并将其转换为所需的值,检查哈希中是否存在,如果找到,则在其中添加并使用该数组,否则创建一个新数组,将其压入该数组并将其保存在哈希中。
  3. You can filter out those children having further children, and recursively call for each of them (filtered) children to process the same logic (it will help you not to call one level of function in stack for recursion) 您可以过滤掉那些有更多子级的子级,然后递归地调用每个(过滤后的)子级来处理相同的逻辑(这将有助于您不必在堆栈中调用一级函数进行递归)

 var obj = {"children":[{"name":"Central","children":[{"name":"Cellophane `Tape","value":10.528979999999999},{"name":"Cellophane Tape","value":10.529},{"name":"File Separator","value":10.529},{"name":"Hard Cover File","value":10.529},{"name":"Highlighter","value":10.529},{"name":"Office Chair","value":10.529},{"name":"Pencil","value":10.529},{"name":"Tape Dispenser","value":10.529},{"name":"File Cabinet","value":21.058},{"name":"Highlighter","value":21.058},{"name":"Office Chair","value":21.058},{"name":"Pencil","value":21.058},{"name":"Plastic Comb Binding","value":21.058},{"name":"Tape Dispenser","value":21.058},{"name":"White Board Markers","value":21.058},{"name":"File Separator","value":23.273360000000004},{"name":"Binder","value":23.2734},{"name":"Cellophane Tape","value":23.2734},{"name":"File Separator","value":23.2734},{"name":"Hard Cover File","value":23.2734},{"name":"Highlighter","value":23.2734},{"name":"Plastic Comb Binding","value":23.2734},{"name":"Tape Dispenser","value":23.2734},{"name":"White Board Markers","value":23.2734},{"name":"Binder","value":64.0017},{"name":"Eraser","value":64.0017},{"name":"File Separator","value":64.0017},{"name":"Office Chair","value":64.0017},{"name":"Plastic Comb Binding","value":64.0017},{"name":"Tape Dispenser","value":64.0017},{"name":"Binder","value":64.00174},{"name":"Tape Dispenser","value":64.00174},{"name":"Binder","value":67.2899},{"name":"Highlighter","value":67.2899},{"name":"Office Chair","value":67.2899},{"name":"Plastic Comb Binding","value":67.2899},{"name":"Tape Dispenser","value":67.2899},{"name":"Cellophane Tape","value":74.2509},{"name":"Office Chair","value":74.2509},{"name":"Pencil","value":74.2509},{"name":"Plastic Comb Binding","value":74.2509},{"name":"White Board Markers","value":74.2509},{"name":"Cellophane Tape","value":79.7194}]}]}; function aggDeep(obj) { let hasChildren = o => o.children && o.children.length, hasNoChildren = o => !(o.children && o.children.length), map = {}, aggDeepRec = ({ name, children }) => { if (hasChildren({ children })) { let leafs = children.filter(hasNoChildren); if (leafs.length) { let entry = (map[name] = map[name] || {name, children: {}}); leafs.forEach(le => { entry.children[le.name] = (entry.children[le.name] || 0) + le.value; }); } children.filter(hasChildren).forEach(c => aggDeepRec(c)); } return map; } return Object.entries(aggDeepRec(obj)).reduce((res, [k, v])=>{ let {name} = v, children = Object.entries(v.children).map(([name, value])=> ({name, value})); return Object.assign(res, {[k]: {name, children}}); }, {}); } var res = aggDeep(obj); console.log(JSON.stringify(res, null, 4)); 

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM