Home > Net >  How can I get sum of array depends on key values?
How can I get sum of array depends on key values?

Time:11-25

I have object as following format :

let objs = [
    {Name : 'A', Y1 : '1', Y2 : '1',Y3 : '1'}
    {Name : 'B', Y1 : '2', Y2 : '3',Y3 : '3'}
    {Name : 'C', Y1 : '1', Y2 : '1',Y3 : '6'}
    ]

I want to achive an object as following :

{Name : 'Total', Y1 : '4', Y2 : '5',Y3 : '10'}

I’ve tired to create the object by using .reduce but think there are more effiecent way to create the object.

let a = objs.reduce((total, obj) => obj['Y1']   total, 0)
let b = objs.reduce((total, obj) => obj['Y2']   total, 0)
let c = objs.reduce((total, obj) => obj['Y3']   total, 0)

//then create new object and merge with exiting object

How can I achieve the object in more effiecent way?

CodePudding user response:

We can merge 3 reduce into only 1 reduce as below:

let objs = [
    {Name : 'A', Y1 : '1', Y2 : '1',Y3 : '1'},
    {Name : 'B', Y1 : '2', Y2 : '3',Y3 : '3'},
    {Name : 'C', Y1 : '1', Y2 : '1',Y3 : '6'}
    ]
    
let result1 = objs.reduce((a,c) =>{
  a.Y1  =  c.Y1
  a.Y2  =  c.Y2
  a.Y3  =  c.Y3
  return a
},{'Name':'Total','Y1':0,'Y2':0,'Y3':0})
console.log(result1)

let result2 = objs.reduce((a,{Y1,Y2,Y3}) =>{
  a.Y1  =  Y1
  a.Y2  =  Y2
  a.Y3  =  Y3
  return a
},{'Name':'Total','Y1':0,'Y2':0,'Y3':0})
console.log(result2)


Update:with dynamic keys

let objs = [
    {Name : 'A', Y1 : '1', Y2 : '1',Y3 : '1'},
    {Name : 'B', Y1 : '2', Y2 : '3',Y3 : '3'},
    {Name : 'C', Y1 : '1', Y2 : '1',Y3 : '6'}
    ]
    
let result = objs.reduce((a,c) =>{
  let keys = Object.keys(c).slice(1)
  keys.forEach(k => {
   a[k]  =  c[k] 
  })
  return a
},{'Name':'Total','Y1':0,'Y2':0,'Y3':0})
console.log(result)

CodePudding user response:

You can do this;

let y1 = 0;
let y2 = 0;
let y3 = 0; 
let objs = [
    {"Name" : 'A', "Y1" : '1', "Y2" : '1', "Y3" : '1'},
    {"Name" : 'B', "Y1" : '2', "Y2" : '3', "Y3" : '3'},
    {"Name" : 'C', "Y1" : '1', "Y2" : '1', "Y3" : '6'}
]

objs.forEach((e)=>{
    y1 = y1   parseInt(e["Y1"]);
    y2 = y2   parseInt(e["Y2"]);
    y3 = y2   parseInt(e["Y3"]);
});

console.log(y1);
console.log(y2);
console.log(y3);

CodePudding user response:

Improving on flyingfox's answer with dynamic key value pairs:

let objs = [
    {Name : 'A', Y1 : '1', Y2 : '1',Y3 : '1', Y4: 'foo', Y5: '1'},
    {Name : 'B', Y1 : '2', Y2 : '3',Y3 : '3', Y4: '2'},
    {Name : 'C', Y1 : '1', Y2 : '1',Y3 : '6', Y5: 'bar'}
    ]
    
let result = objs.reduce((a,c) =>{
  const copy = {...c};
  delete copy.Name;
  const keys = Object.keys(copy)
  for (const k of keys) {
   const num = parseInt(c[k]);
   if (isNaN(num)) continue;
   if (a[k] === undefined) a[k] = 0;
   a[k]  = num; 
  }
  return a
},{'Name':'Total'})

console.log(result)

CodePudding user response:

let objs = [
    { Name: "A", Y1: "1", Y2: "1", Y3: "1" },
    { Name: "B", Y1: "2", Y2: "3", Y3: "3" },
    { Name: "C", Y1: "1", Y2: "1", Y3: "6" },
  ];
  let tempY1 = 0;
  let tempY2 = 0;
  let tempY3 = 0;
  for (let i = 0; i < objs.length; i  ) {
    tempY1  = parseInt(objs[i].Y1);
    tempY2  = parseInt(objs[i].Y2);
    tempY3  = parseInt(objs[i].Y3);
  }
  let newObj = { name: "total", Y1: tempY1, Y2: tempY2, Y3: tempY3 };
  console.log(newObj);

In this solution, we simply take the sum of all the key values by for loop for which you needed to store it in the temp variable, and after the completion of for loop, you good the data which you want in your question.

In case of any confusion drop a comment.

Thanks

CodePudding user response:

Using lodash - spread the array of objects into _.mergeWith() with the logic of summing the numeric values of all keys but Name. If the key is Name return "Total":

const objs = [{Name : 'A', Y1 : '1', Y2 : '1',Y3 : '1'},   {Name : 'B', Y1 : '2', Y2 : '3',Y3 : '3'}, {Name : 'C', Y1 : '1', Y2 : '1',Y3 : '6'}]
    
const result = _.mergeWith({}, ...objs, (a = 0, b, key) => 
  key === 'Name' ? 'Total' : a    b
)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG ljU96qKRCWh quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

If you the sums to be strings as well, wrap the sum expression with String():

const objs = [{Name : 'A', Y1 : '1', Y2 : '1',Y3 : '1'},   {Name : 'B', Y1 : '2', Y2 : '3',Y3 : '3'}, {Name : 'C', Y1 : '1', Y2 : '1',Y3 : '6'}]
    
const result = _.mergeWith({}, ...objs, (a = 0, b, key) => 
  key === 'Name' ? 'Total' : String( a    b)
)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG ljU96qKRCWh quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Note: I'm using unary plus ( ) to convert strings to number, so this expression a b converts both parameters to numbers, and then adds them.

  • Related