1

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

infodev
  • 4,673
  • 17
  • 65
  • 138

4 Answers4

4

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.

slider
  • 12,810
  • 1
  • 26
  • 42
  • When using TS I get this waring in VS Code `[ts] Cannot invoke an expression whose type lacks a call signature. Type '((...items: { item1: string; }[]) => number) | ((...items: { item2: string; }[]) => number)' has no compatible call signatures.` – infodev Oct 22 '18 at 20:35
  • @infodev I don't think I can help you without more information. Perhaps you want to take a look at https://stackoverflow.com/questions/39691889/error-cannot-invoke-an-expression-whose-type-lacks-a-call-signature ? – slider Oct 22 '18 at 21:13
1

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)
Calvin Nunes
  • 6,376
  • 4
  • 20
  • 48
1

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)
Calvin Nunes
  • 6,376
  • 4
  • 20
  • 48
Daniel Choi
  • 194
  • 1
  • 5
0

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

wc_coder
  • 88
  • 6