简体   繁体   English

如何递归循环 javascript 中的 object 并对所有值求和?

[英]How to recursively loop through an object in javascript and sum all the values?

If this is my object如果这是我的 object

{
   "a":{
      "a1":5,
      "b":{
         "b1":10,
         "b2":15,
         "c":{
            "c1":15
         }
      }
   }
}

the output I want is:我想要的 output 是:

{a:45 b:40, c: 15}

c => 15
b => 10 + 15 + c
a => 5 + b + c

how do I achieve this?我如何实现这一目标? been banging my head against a brick wall all day一整天都在用头撞砖墙

so far I've tried:到目前为止我已经尝试过:

let constructedTotals = {};
const calculateVals = (vals) => {
  return vals
    .map((val) => {
      if (typeof val === "object" && Object.keys(val).length > 0) {
        return Object.values(val);
      }
      return val;
    })
    .flatMap((x) => x)
    .filter((x) => typeof x === "number")
    .reduce((a, b) => a + b, 0);
};

const constructing = (construct) => {
  return Object.entries(construct).map((entry) => {
    if (typeof entry[1] === "object") {
      constructing(entry[1]);
      constructedTotals = {
        ...constructedTotals,
        [entry[0]]: calculateVals(Object.values(entry[1])),
      };

    } else {
        console.log('here')
    }
  });
};

 const data = { a: { a1: 5, b: { b1: 10, b2: 15, c: { c1: 15, }, }, }, }; const outputObj = {}; function addValue(data) { for (const [key, value] of Object.entries(data)) { const outKey = key.at(0); outputObj[outKey]??= 0; if (typeof value === "object") addValue(value); else for (const svKey in outputObj) outputObj[svKey] += value; } } addValue(data); console.log(outputObj);

You could handover the parent key and add the total of nested keys.您可以移交父键并添加嵌套键的总数。

 const sum = (object, parent = '') => Object.entries(object).reduce((r, [k, v]) => { if (v && typeof v === 'object') { Object.assign(r, sum(v, k)); if (parent) r[parent] += r[k]; } else { r[parent] = (r[parent] || 0) + v; } return r; }, {}), data = { a: { a1: 5, b: { b1: 10, b2: 15, c: { c1: 15 } } } }, result = sum(data); console.log(result);

you can try this:你可以试试这个:

let obj = {
   "a":{
      "a1":5,
      "b":{
         "b1":10,
         "b2":15,
         "c":{
            "c1":15
         }
      }
   }
}

let recusive = (obj,output)=>{
  if(typeof(obj) == "object"){
    let keys = Object.keys(obj)
    let sum = 0;
    keys.forEach(key => {
        if(typeof(obj[key]) == "object"){
            output[key] = recusive(obj[key],output)
            sum += output[key]
        }
        else
          sum+= obj[key]    
    });
    return sum
  }
  else
    return obj;
}

let warp = (obj) => {
  let output = {};
  recusive(obj, output);
  return output;
}
console.log(warp(obj))

The output will hold the result, it worked for the example you gave, might throw if you give it an object that is build differently output 将保存结果,它适用于您给出的示例,如果您给它一个构建不同的 object 可能会抛出

You could create a reducer function that:您可以创建一个 reducer function :

  • Builds an object by key通过密钥构建一个 object
  • Accumulates the total of the numbered keys for each node, and adds the previous total累加每个节点的编号键的总数,并添加以前的总数

 const main = () => { const result = reduce(tree, (acc, node) => { let currKey, prevKey, currVal = 0; for (const prop in node) { const [, key] = prop.match(/^(\w)\d$/)?? []; currKey??= key; if (key) currVal += +node[prop]; prevKey??= prop.match(/^(\w)$/)?.[1]; } if (currKey) { acc[currKey] = (acc[prevKey]?? 0) + currVal; } }); console.log(result); // { "c": 15, "b": 40, "a": 45 } }; const reduce = (node, visitor) => { const result = {}; traverse(node, visitor, result); return result; }; const traverse = (node, visitor, result) => { if (typeof node === 'object') { for (const prop in node) { traverse(node[prop], visitor, result); } } visitor(result, node); }; const tree = { a: { a1: 5, b: { b1: 10, b2: 15, c: { c1: 15 } } } }; main();
 .as-console-wrapper { top: 0; max-height: 100%;important; }

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

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