infodev
infodev

Reputation: 5245

reduce array of objects

I have an array of objects. I would concatenate items as follow:

obj2 = [{ rowNumber:33, rows:[{item1:'ItemOne'}]}, { rowNumber:44, rows:[{item2:'ItemTwo'}]}]  
===> new obj = [{ rowNumber:77, rows:[{item1:'ItemOne'},{item2:'ItemTwo'}]}] 

Here's my code

let newobj=obj2.reduce((current , next)=> {
     current.rowNumber+next.rowNumber;
     current.rows.push(next.rows);
     return next;
});
console.log(JSON.stringify(newobj))

What actually get this only the second element

{"rowNumber":44,"rows":[{"item2":"ItemTwo"}]}

PS: I'm using Typescript

Upvotes: 1

Views: 155

Answers (4)

Daniel Choi
Daniel Choi

Reputation: 194

I believe it is because you are trying to input the last element, next, to the first element, current.

As you know, Reduce functions allow you to take an array and returns a single value. It evaulates each element on the array one at a time, using the last value to get a new value.

So you should do something like this:

let obj2 = [{ rowNumber:33, rows:[{item1:'ItemOne'}]}, { rowNumber:44,   rows:[{item2:'ItemTwo'}]}];

let newobj=obj2.reduce((current , next)=> {
 next.rowNumber += current.rowNumber;
 next.rows.push(current.rows);
 return next;
});

console.log(newobj)

Upvotes: 1

slider
slider

Reputation: 12990

You are not updating the current object (which should actually be called accumulator). Also, you're pushing to current but returning next. Here's a fixed version.

let obj2 = [{ rowNumber:33, rows:[{item1:'ItemOne'}]}, { rowNumber:44, rows:[{item2:'ItemTwo'}]}];

let newobj = obj2.reduce((current , next) => {
     current.rowNumber += next.rowNumber;
     current.rows.push(...next.rows);
     return current;
});
console.log(JSON.stringify(newobj))

I would fix the variable names in the reduce function to (acc, current) => {...} just to adhere to convention and so that it's clear that you want to use current to update acc and then return acc.

Upvotes: 4

Calvin Nunes
Calvin Nunes

Reputation: 6516

If you know the structure of your obj2 array, you can go with the below solution, that will have be single object in the final with the sum of rowNumbers and an array of rows.

take a look, please:

let obj2 = [{ rowNumber:33, rows:[{item1:'ItemOne'}]}, { rowNumber:44, rows:[{item2:'ItemTwo'}]}]

let singleObj = {
  rowNumber: 0,
  rows: [],
}
for (let obj of obj2){
  singleObj.rowNumber += obj.rowNumber;
  if (obj.hasOwnProperty('rows')){
    for (var row of obj.rows){
      singleObj.rows.push(row)
    }
  }
}
//HERE YOU CAN STRINGIFY() IT
console.log(singleObj)

Upvotes: 1

wc_coder
wc_coder

Reputation: 88

Try using the Javascript Array.concat() method instead of push()

You can check it out here:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

Upvotes: 0

Related Questions