Santhosh Kumar
Santhosh Kumar

Reputation: 45

How to sum the values in this object of objects in javascript?

const ob = {
    a: 1,
    b: {
        c: 3,
        d: 6,
        e: {
            f: {
                g: 3,
                h: {
                    i: 5,
                    j: {
                        k: 7
                    }
                }
            }
        }
    }
};

Any methods to solve this code?

I have no idea how to solve this code.

For abovementioned input I would expect a result of 1 + 3 + 6 + 3 + 5 + 7 = 25. So what I want to return from a function sumObject(ob) is: 25

Upvotes: 3

Views: 336

Answers (7)

MoRe
MoRe

Reputation: 2372

const ob = {
    a: 1,
    b: {
        c: 3,
        d: 6,
        e: {
            f: {
                g: 3,
                h: {
                    i: 5,
                    j: {
                        k: 7
                    }
                }
            }
        }
    }
}; 

const sum = data =>
   Object
   .keys(data)
   .reduce((a,b) => a + (typeof(s = data[b]) == "number" ? s : sum(s)), 0);

console.log(sum(ob))

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386578

You could get the value of the objects and check if the value is an object, then take the result of the nested objects or call the handed over sum function for accumulator and actual value.

This approach works with a function which takes

  • an object
  • an accumulator function
  • a start value

This function works as well for getting all values with different accumulator function and an array as startValue.

const
    reduce = (object, fn, startValue) => Object
        .values(object)
        .reduce(
            (r, v) => v && typeof v === 'object' ? reduce(v, fn, r) : fn(r, v),
            startValue
        ),
    data = { a: 1, b: { c: 3, d: 6, e: { f: { g: 3, h: { i: 5, j: { k: 7 } } } } } },
    total = reduce(data, (a, b) => a + b, 0);

console.log(total);

Upvotes: 0

mstephen19
mstephen19

Reputation: 1926

Try recursion. This will support any amount of nested object at any level of nesting.

const sumAllNumbers = (object, total = 0) => {
    const nextValues = [];

    for (const value of Object.values(object)) {
        if (typeof value === 'number') total += value;
        if (typeof value === 'object') nextValues.push(Object.values(value));
    }

    if (!nextValues.length) return total;

    return sumAllNumbers(nextValues.flat(), total);
};

// adds up to 25
const testCase1 = {
    a: 1,
    b: {
        c: 3,
        d: 6,
        e: {
            f: {
                g: 3,
                h: {
                    i: 5,
                    j: {
                        k: 7,
                    },
                },
            },
        },
    },
};

// adds up to 30
const testCase2 = {
    a: 1,
    b: 2,
    c: {
        a: 1,
        b: 2,
        c: 3,
        d: {
            a: 5,
            b: {
                c: {
                    d: {
                        e: 1,
                    },
                },
            },
        },
    },
    d: {
        g: {
            f: {
                c: 10,
            },
        },
    },
    e: {
        f: {
            a: 1,
            g: {
                a: 4,
            },
        },
    },
};

// Your original test case
console.log(sumAllNumbers(testCase1));

// My much more demanding test case
console.log(sumAllNumbers(testCase2));

Upvotes: 0

KoderM
KoderM

Reputation: 380

If you don't understand some of the other answers, this is an easier solution to understand:

function sumObject(obj){
  
  let result = 0;
  
  for(let i of Object.values(obj)){ //we iterate through all values in obj
    
    if(typeof i == "number"){ //if the current value of i is a number
      
      result+=i; //then add that to the result
      
    } else { //otherwise, it will be an object
      
      result+=sumObject(i); //so we call the function on itself to iterate over this new object
      
    }
    
  }
  
  return result; //finally, we return the total
  
}

console.log(sumObject(ob));

Upvotes: 1

Hassan Imam
Hassan Imam

Reputation: 22534

You can recursively sum the value of each object using array#reduce and Object.values()

const ob = { a: 1, b: { c: 3, d: 6, e: { f: { g: 3, h: { i: 5, j: { k: 7 } } } } } },
      getSum = o =>
        Object.values(o).reduce((s, v) => {
          s += typeof v === 'object' ? getSum(v): v;
          return s;
         }, 0);
console.log(getSum(ob));

Upvotes: 0

Nick Vu
Nick Vu

Reputation: 15520

You can try reduce with recursion

The condition for the sum is

  • If the current value is a number, sum it with result
  • If the current value is not a number (in your case, it's an object), call the function sumObject recursively with current result

const ob = {
  a: 1,
  b: {
    c: 3,
    d: 6,
    e: {
      f: {
        g: 3,
        h: {
          i: 5,
          j: {
            k: 7
          }
        }
      }
    }
  }
};

function sumObject(data, result = 0) {
  return Object.values(data).reduce((sum, value) => typeof value === 'number' ? sum + value : sumObject(value, sum), result)
}

console.log(sumObject(ob))

Upvotes: 5

madprops
madprops

Reputation: 4023

You can do this to extract all values into an array of numbers and then sum that array:

const getObjectValues = (obj) => (obj && typeof obj === 'object')
 ? Object.values(obj).map(getObjectValues).flat()
 : [obj]


let nums = getObjectValues(ob)

let sum = nums.reduce((a, b) => a + b, 0)

Upvotes: 0

Related Questions