0

If you have an array of objects like so:

enter image description here

What's the best way to add all numerical values in each object so each one looks something like this:

{category: "A", total: 44}

So in the 0th item in the original array, 0+23+21 is 24, and is now represented by the new 'total' key.

Bearing in mind that the 'keys' with numerical values in the original array e.g. 'col2' are randomly generated (so another array like the original can have keys like 'somethingelse'.

I've attempted it with the following, but I believe it's not written correctly:

newArrayOfObjects.forEach(element => {
    Object.values(element).reduce((a, b) => a + b);
});

It may be good to know but the 'key' category always exists in each object and is fixed. All other key values are numerical and there'll always be more than one.

2
  • Images are OK but isn't mandatory but code as a minimal reproducible example is required 99% of the time. Commented Jun 20, 2022 at 9:51
  • const results = newArrayOfObjects.map(element => Object.values(element).reduce((sum,value) => typeof value === 'number' ? sum+value : sum, 0)) Commented Jun 20, 2022 at 9:52

5 Answers 5

4

Please check this.

const array = [
  {
    category: 'A',
    col1: 1,
    col2: 2,
    col3: 3,
  },
  {
    category: 'B',
    col1: 2,
    col2: 3,
    col3: 4,
  }
]

const result = array.map(obj => {
  const total = Object.values(obj).reduce((acc, value) => {
    if (typeof value === 'number') {
      return acc + value;
    }
    return acc;
  }, 0)
  return {
    category: obj.category,
    total
  }
})

console.log(result)

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

2 Comments

it could be solved with O(n) complexity (please see my solution below), no need to have O(n^2).
But in your example, you restrict the numeric value keys to col2 and col3, but @One_for_all said that key can be any value, so I'm sorry your answer isn't valid.
1

You could use Array.map() along with Array.reduce() to sum the numeric values in the array.

We'd create a toNumber() function to get the numeric value of any property. If this is not a number, it will return 0 (keeping the total unchanged).

let arr = [
   { a: 0, category: "a", col2: 23, col3: 21 },
   { b: 0, category: "b", x: 100, y: 10, z: 1 },
   { j: 0, category: "x", foo: 25, bar: 50, meta: 'content' },
]

function toNumber(n) {
    return isNaN(n) ? 0: n;
}

function sumTotals(a) {
    return a.map(({ category, ...obj}) => {
        const total = Object.values(obj).reduce((total, value) => { 
            return total + toNumber(value); 
        }, 0);
        return { category, total };
    })
}

console.log('Totals:', sumTotals(arr))
.as-console-wrapper { max-height: 100% !important; }

Comments

0

arr = [{x:1}, {x:3}]

arr.reduce((accumulator, current) => accumulator + current.x, 0);

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0
var data = [
    { "category": "A", "col0": 5, "col1": 8, "some": "thing"},
    { "category": "B", "col1": 3, "col2": 5}
];

var res = data.map((it) => {
    const { category, ...rest } = it;
    return {
      ...it,
      total: Object.values(rest).reduce(
        (prev, curr) =>
          typeof curr === "number" ? prev + curr : prev, // add if the current value is numeric
          0
      )
    }
});

console.log(res);

/**
[
  {"category":"A","col0":5,"col1":8,"some":"tst","total":13}, 
  {"category":"B","col1":3,"col2":5,"total":8}
]
**/

Comments

0

I think you are on the right way, you just need to do a bit more destructuring and type checking:

const aggregated = newArrayOfObjects.map((obj) =>
  Object.entries(obj).reduce(
    (newObj, [key, value]) => ({
      ...newObj,
      ...(typeof value === "number"
        ? { total: newObj.total + value }
        : { [key]: value }),
    }),
    { total: 0 }
  )
);

First, you map all objects to their representations as key-value-pairs. Then you iterate over these key-value pairs and keep all non-numerical values and their respective keys, while dropping key-value-pairs with a numerical value and replacing them by a property in which you aggregate the total value.

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.