簡體   English   中英

如何總結一個嵌套的Javascript對象數組的所有葉節點?

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

目前,我有一個嵌套的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
        }
      ]
    }
  ]
}

因此,我想做的是遍歷此數組的所有葉節點,然后像這樣將其聚合到每個父節點

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;
                          })

                      };
                  }
              };

像這樣,但是使用reduce函數會返回一個平面數組。 如果是這樣,那么如何將這個平面數組重新插入到我的葉子節點中?

我能夠檢索所有葉節點並對其進行聚合,因此我的預期輸出是這樣的,但我希望它與每個父節點一致。

我的數據https : //api.myjson.com/bins/gki6c

預期產量:

[
  {
    "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. 您可以維護在對象中找到的名稱及其葉節點的hash
  2. 您可以過濾葉節點並將其轉換為所需的值,檢查哈希中是否存在,如果找到,則在其中添加並使用該數組,否則創建一個新數組,將其壓入該數組並將其保存在哈希中。
  3. 您可以過濾掉那些有更多子級的子級,然后遞歸地調用每個(過濾后的)子級來處理相同的邏輯(這將有助於您不必在堆棧中調用一級函數進行遞歸)

 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