0

How find sum of all value in that object? In object included array with another object with value and may be "next" array with similar structure object.

{
  value: 4,
  next: [
    {
      value: 3,
      next: [...]
    },
    {
      value: 3,
      next: [...]
    },
    ...
  ]
}
Drop
  • 1,394
  • 3
  • 15
  • 25
  • Possible duplicate of [How to sum the values of a JavaScript object?](https://stackoverflow.com/questions/16449295/how-to-sum-the-values-of-a-javascript-object) – Lewis Mar 12 '19 at 10:51

5 Answers5

5

You would need recursion to deal with the arbitrary nesting of your object:

const nestedSum = o => (o.next || []).reduce((acc, o) => acc + nestedSum(o), o.value);

// Demo
const data = {
  value: 4,
  next: [{
      value: 3,
      next: [{value: 5}]
    }, {
      value: 3,
      next: []
    },
  ]
};

console.log(nestedSum(data));
trincot
  • 317,000
  • 35
  • 244
  • 286
  • it seem not correct if change next:[] to next: [{value:5}] – Hien Nguyen Mar 12 '19 at 10:56
  • I added that case to the snippet. – trincot Mar 12 '19 at 10:57
  • @trincot Can you make me explain how it be with `o.value`? How i see first we check there have array or not, for work with reduce, then we use recursion and then i don't understand with that part `, o.value` :) – Drop Mar 12 '19 at 11:18
  • `o.value` is passed as second argument to `reduce`, so that the sum that is being accumulated via the callback with start with that value (as opposed to starting at 0). We could of course pass 0 instead, and then add `o.value` to the return value of `reduce`, but that is just one extra operation. Better start the sum directly with `o.value`. – trincot Mar 12 '19 at 12:07
2

Use reduce and Object.entries to sum the values recursively:

const obj = {
  value: 4,
  next: [{
    value: 3,
    next: [{ value: 1 }]
  }, {
    value: 3,
    next: [{ value: 2, next: [] }]
  }]
};

const sum = (obj) =>
  Object.entries(obj).reduce((acc, [k, v]) => acc + (
    k === 'next'
      ? v.map(sum).reduce((s, x) => s + x, 0)
      : k === 'value' ? v : 0)
  , 0);

console.log(sum(obj));
jo_va
  • 13,504
  • 3
  • 23
  • 47
2

function sum(obj, current = 0) {
   const nextSum = (obj.next || []).reduce((nextSum, obj) => nextSum + sum(obj, current), 0)
   return current + nextSum + obj.value
}

const example = {
  value: 4,
  next: [
    {
      value: 3,
      next: [{
        value: 7
      }]
    },
    {
      value: 3
    }
  ]
}

console.log(sum(example)) // must be 17
AlexOwl
  • 869
  • 5
  • 11
1

The structure of your object is called tree Tree (data structure). You can use breadth-first or depth-first approach to traverse the tree and gather the sum along the way.

Other answers say you have to go recursively but you can do it iteratively with the breadth-first approach, I show you both approaches down in the code snippet.

I've expanded your data sample adding null values where there is supposedely no next values (you could use any kind of check really).

let data = {
  value: 4,
  next: [
    {
      value: 3,
      next: [
        {
          value: 5,
          next: null
        },
        {
          value: 6,
          next: null
        }
      ]
    },
    {
      value: 2,
      next: [
        {
          value: 2,
          next: null
        },
        {
          value: 3,
          next: [
            {
              value: 7,
              next: null
            },
            {
              value: 8,
              next: null
            }
          ]
        }
      ]
    }
  ]
}

// iterative approach
function breadthFirst(node){
  let sum = 0
  let q = [node]

  while(q.length > 0){
    let node = q.pop()
    sum += node.value

    if (node.next !== null) {
      for (let other of node.next){
        q.push(other)
      }
    }
  }

  return sum
}

console.log('breadthFirst sum (iterative):', breadthFirst(data))

// recursive apporach
function depthFirst(node){
  let sum = 0

  function recursion(node){
    sum += node.value

    if (node.next !== null) {
      for (let other of node.next){
        recursion(other)
      }
    }
  }

  recursion(node)

  return sum
}

console.log('depthFirst sum (recursive):', depthFirst(data))
Fredo Corleone
  • 544
  • 1
  • 6
  • 16
0

You need a recursive function and check if the value of a key is a number then add with the variable , else if it is an array like next then iterate through it and again call the same function with a new object

let data = {
  value: 4,
  next: [{
      value: 3,
      next: [{
        value: 4
      }, {
        value: 5
      }]
    },
    {
      value: 3,
      next: [{
        value: 2
      }]
    }
  ]
}

let sum = 0;

function findSum(obj) {
  for (let keys in obj) {
    if (typeof obj[keys] === 'number') {
      sum += obj[keys];
    } else if (Array.isArray(obj[keys]) && obj[keys].length > 0) {
      obj[keys].forEach(function(item) {
        findSum(item)

      })
    }
  }
}

findSum(data);
console.log(sum)
brk
  • 48,835
  • 10
  • 56
  • 78