0

I want to calculate the total sum of all the 'val' in this object. The final output should be 113. I tried searching but couldn't find a similar problem on stackoverflow.

const object = {
  val: 10,
  child: [
    {
      val: 20,
      child: [
        {
          val: 25,
          child: []
        },
        {
          val: 28,
          child: []
        }
      ]
    },
    {
      val: 30,
      child: []
    }
  ]
};

What I tried is this. I know this is not the best approach and would love to see a better approach to this.

const object = {
  val: 10,
  child: [
    {
      val: 20,
      child: [
        {
          val: 25,
          child: []
        },
        {
          val: 28,
          child: []
        }
      ]
    },
    {
      val: 30,
      child: []
    }
  ]
};

function sum() {
 let k = object.val;
 if(object.child.length>0){
 object.child.map(item => {
 
 k += item.val;
 if(item.child.length>0){
 item.child.map(item => k += item.val)
 }
 })
 }
 
 return k
}

const result = sum(object);
console.log(result);

You can find the problem here - https://codesandbox.io/s/young-night-ulnfl?file=/src/index.js

I was also thinking something like flat() could have helped but that is only for arrays.

2

4 Answers 4

1

Recursive Array#reduce()

const object = { val: 10, child: [{ val: 20, child: [{ val: 25, child: [] }, { val: 28, child: [] }] }, { val: 30, child: [] }] };

const sumObjectVals = (arr) => arr
  .reduce((a, obj) => (
    a += (obj.child.length
      ? obj.val + sumObjectVals(obj.child)
      : obj.val), a), 0);

console.log(sumObjectVals([object]))

Sign up to request clarification or add additional context in comments.

Comments

0

You could create a recursive node visitor function.

const tree = { val: 10, child: [{ val: 20, child: [{ val: 25, child: [] }, { val: 28, child: [] }] }, { val: 30, child: [] }] }

const visitNodes = (obj, visitor, key) => {
  if (typeof obj === 'object') {
    for (let key in obj) {
      visitNodes(obj[key], visitor, key);
    }
  } else {
    visitor(obj, key);
  }
};

let total = 0;
visitNodes(tree, (val, key) => {
  if (key === 'val') {
    total += val;
  }
});
console.log(`Total: ${total}`);

Alternatively, you could have an accumulator that can add all your values for you.

Edit: Altered the function signature to take a custom "child" prop.

const tree = { val: 10, child: [{ val: 20, child: [{ val: 25, child: [] }, { val: 28, child: [] }] }, { val: 30, child: [] }] }

const accumulateValues = (obj, visitor, childProp = null, acc = 0) => {
  if (typeof obj === 'object') {
    acc += visitor(obj);
    if (Array.isArray(obj[childProp])) {
      acc += obj[childProp].reduce((acc, child) =>
        accumulateValues(child, visitor, childProp, acc), 0);
    }
  }
  return acc;
};

const total = accumulateValues(tree, ({ val }) => val, 'child');
console.log(`Total: ${total}`);

Comments

0
const object = {
  val: 10,
  child: [
    {
      val: 20,
      child: [
        {
          val: 25,
          child: []
        },
        {
          val: 28,
          child: []
        }
      ]
    },
    {
      val: 30,
      child: []
    }
  ]
};

function sum(obj, summ) {
  summ += obj.val;

  if(obj.child.length > 0) {
    obj.child.forEach(x => summ = sum(x, summ))
  }

  return summ;
}

const result = sum(object, 0);
console.log(result);

Comments

0

// You can use multiple reduce array method to get the result.

const object = {
  val: 10,
  child: [
    {
      val: 20,
      child: [
        {
          val: 25,
          child: []
        },
        {
          val: 28,
          child: []
        }
      ]
    },
    {
      val: 30,
      child: []
    }
  ]
};

const results = object.child.reduce((totals, current)=> {
  const innerResult = current.child.reduce((total, cur) => {
    return total + cur.val
  }, 0);
  return totals + current.val + innerResult;
}, object.val);

console.log(results);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.