2

I have a dynamic array and I need to perform a sum of it.

 {ClientName: "A", Alex: 2, Da: 0, Cal: 0}
{ClientName: "b", Alex: 0, Da: 0, Cal: 4}
{ClientName: "c", Alex: 1, Da: 0, Cal: 5}
{ClientName: "d", Alex: 2, Da: 0, Cal: 0}

in this array, client name is fixed but other columns like Alex, Da, Cal are dynamic and will vary. i need to create a generic function in typescript where output will be like this.

{ClientName: "Total", Alex: 5, Da: 0, Cal: 9}
2
  • 8
    please add an attempt. Commented Jan 4, 2019 at 12:51
  • 1
    “Columns are dynamic” means the property names are arbitrary and could be anything? Or is there a certain set of possible column names? Commented Jan 4, 2019 at 12:57

5 Answers 5

3

You can try something like this:

Idea:

  • Uses Object.keys to get all enumerable keys.
  • Loop over them ans set them to default if not found. Then add current object's value.
  • Since you need hardcoded value for ClientName, you can set it either in loop or set it after loop.

const data = [
  {ClientName: "A", Alex: 2, Da: 0, Cal: 0},
  {ClientName: "b", Alex: 0, Da: 0, Cal: 4},
  {ClientName: "c", Alex: 1, Da: 0, Cal: 5},
  {ClientName: "d", Alex: 2, Da: 0, Cal: 0},
]

const output = data.reduce((acc, item) => {
  Object
  .keys(item)
  .forEach((key) => {
    acc[key] = (acc[key] || 0) + item[key]
  });
  acc.ClientName = 'Total'
  return acc;
}, {})

console.log(output)

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

Comments

2

You could reduce the wanted values.

var data = [{ ClientName: "A", Alex: 2, Da: 0, Cal: 0 }, { ClientName: "b", Alex: 0, Da: 0, Cal: 4 }, { ClientName: "c", Alex: 1, Da: 0, Cal: 5 }, { ClientName: "d", Alex: 2, Da: 0, Cal: 0 }],
    total = data.reduce((a, { ClientName, ...b }) => Object.assign(
        {},
        a,
        { ClientName: 'total' },
        ...Object.entries(b).map(([k, v]) => ({ [k]: (a[k] || 0) + v }))
    ));
    
console.log(total);

Comments

0

Something along these lines should work as long as all keys besides ClientName are defined as numbers

arr.reduce((sumObject, item) => {
  Object.keys(item).forEach(key => {
    if(key === 'ClientName'){
      return false
    }

    if(!sumObject[key]) {
      sumObject[key] = item[key]
    } else {
      sumObject[key] += item[key]
    }
  })

   return sumObject
}, {ClientName: 'Total'})

Comments

0

You can iterate with reduce to generate single output and to merge the key count you can use Object.keys and map will allow you to iterate over your object keys. Also added one dynamic key Abc: 9 just to verify the result.

const object = [{
    ClientName: "A",
    Alex: 2,
    Da: 0,
    Cal: 0
  },
  {
    ClientName: "b",
    Alex: 0,
    Da: 0,
    Cal: 4
  },
  {
    ClientName: "c",
    Alex: 1,
    Da: 0,
    Cal: 5
  },
  {
    ClientName: "d",
    Alex: 2,
    Da: 0,
    Cal: 0,
    Abc: 9
  },
]

const result = object.reduce((accumulator, currentValue) => {
  Object.keys(currentValue).map((indexKey) => {
    accumulator[indexKey] = (accumulator[indexKey] || 0) + currentValue[indexKey]
  });
  accumulator.ClientName = "Total";
  return accumulator;
})

console.log(result);

3 Comments

Your solution is exactly same as mine. Please check other answers before posting
Yes I do agree, but It seems similar but not exactly, See in you code there is forEach which is less optimized than .map which is being used in my solution. Anyways I have already voted up for your solution.
using a map without return statement is so much worse. Also i don't think map is more optimised compared to forEach but that discussion can be done later
-1
 let arr = [
    {ClientName: "A", Alex: 2, Da: 0, Cal: 0},
    {ClientName: "b", Alex: 0, Da: 0, Cal: 4},
    {ClientName: "c", Alex: 1, Da: 0, Cal: 5},
    {ClientName: "d", Alex: 2, Da: 0, Cal: 0}
];

let output = arr.reduce((curr, next) => {
   return {ClientName: "Total", Alex: (curr.Alex + next.Alex ), Da: (curr.Da + next.Da), Cal: (curr.Cal + next.Cal)};
});

console.log(output);

Check this can get the answer simply

2 Comments

OP is looking for a solutions that handles Dynamic columns
yes you are right , it shoud not work for dynamic columns.thank you,

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.