Dennis
Dennis

Reputation: 1975

How to sum values without knowing their key names in es6 (TypeScript)

I have this object. Keys are changeable. They are not fixed so I don't want to rely on key.

interface Inf {
 [key: string]: number
}


const obj: Inf = {
  '2020-01-01': 4,
  '2020-01-02': 5,
}

const obj2: Inf = {
  '2020-01-05': 10,
  '2020-02-10': 15,
}

const finalObj = { one: obj, two: obj2, ... }

What I want to do is sum 10 + 15 + 4 + 5 regardless their key names. I have lodash installed and it has sumBy but it excepts input as array, however, mine is full object.

How can I get 34 in total with this object? Actually my question is half like What is the best way for doing such operation? I know I can do;

let x = 0

Object.values(obj).forEach(o => {
   x += o
})

But is there a better way? Maybe shorter, faster?

Upvotes: 1

Views: 166

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1075855

You've clarified in the comments that you're only dealing with a single layer (as shown in the question). I'd probably use a simple nested loop:

let sum = 0;
for (const obj of Object.values(finalObj)) {  // Loop through the objects
    for (const value of Object.values(obj)) { // Loop through the values
        sum += value;
    }
}

This is very like Nikita's solution, but keeping the loops explicit. :-)

Live Example:

const obj = {
    "2020-01-01": 4,
    "2020-01-02": 5,
};
const obj2 = {
    "2020-01-05": 10,
    "2020-02-10": 15,
};
const finalObj = { one: obj, two: obj2 };

let sum = 0;
for (const obj of Object.values(finalObj)) {
    for (const value of Object.values(obj)) {
        sum += value;
    }
}

console.log(sum);

Upvotes: 2

Nikita Madeev
Nikita Madeev

Reputation: 4380

You can use Object.values and reduce for sum. Works with only one level of objects like in your example.

const obj = {
    "2020-01-01": 4,
    "2020-01-02": 5,
};
const obj2 = {
    "2020-01-05": 10,
    "2020-02-10": 15,
};
const finalObj = { one: obj, two: obj2 };

const result = Object.values(finalObj).reduce((a, b) => a + Object.values(b).reduce((a1, b1) => a1 + b1, 0), 0);

console.log(result);

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386883

You could take a recursive approach for nested objects.

const
    add = object => Object
        .values(object)
        .reduce((s, v) => s + (v && typeof v === 'object' ? add(v) : v), 0),
    one = { '2020-01-01': 4, '2020-01-02': 5 },
    two = { '2020-01-05': 10, '2020-02-10': 15 },
    finalObj = { one, two },
    total = add(finalObj);

console.log(total);

Upvotes: 3

Related Questions