Mormoran
Mormoran

Reputation: 791

Merge objects in array with similar key

I have an array of objects:

objArray = [
    {x: 1, y: 7},
    {x: 2, y: 14},
    {x: 1, z: 9},
    {x: 2, z: 18}
    {x: 1, n: 6}
    {x: 2, n: 16}
]

Is there an efficient way to merge for "X" without a for loop? so that I end up with:

objArray = [
    {x: 1, y: 7, z: 9, n: 6},
    {x: 2, y: 14, z: 18, n: 16}
]

So look for common objArray[n]["x"] and merge all hits into one object? It's OK to modify the original array or create a new one.

I'm aware this can be done with a loop, but I'm trying to avoid too many loops for this implementation, though I'm not sure if a reduce or a filter would work for this.

Upvotes: 1

Views: 80

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386578

You could take a Map and group by property x.

var array = [{ x: 1, y: 7 }, { x: 2, y: 14 }, { x: 1, z: 9 }, { x: 2, z: 18 }, { x: 1, n: 6 }, { x: 2, n: 16 }],
    result = Array.from(
        array
            .reduce((m, o) => m.set(o.x, Object.assign({}, m.get(o.x), o)), new Map)
            .values()
    );
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 3

Paul
Paul

Reputation: 141829

You can do it with Array#reduce:

const objArray = [
    {x: 1, y: 7},
    {x: 2, y: 14},
    {x: 1, z: 9},
    {x: 2, z: 18},
    {x: 1, n: 6},
    {x: 2, n: 16},
]

const result = Object.values( objArray.reduce( 
  (p,c) => (p[c.x] = Object.assign( {}, p[c.x], c ), p ), {}
) );

console.log( result );

Upvotes: 3

Nenad Vracar
Nenad Vracar

Reputation: 122047

You could use reduce method to build an object and then Object.values to get an array.

const data = [{"x":1,"y":7},{"x":2,"y":14},{"x":1,"z":9},{"x":2,"z":18},{"x":1,"n":6},{"x":2,"n":16}]
const res = data.reduce((r, {x, ...rest}) => {
  if(!r[x]) r[x] = {x, ...rest}
  else Object.assign(r[x], rest);
  return r;
}, {})

const result = Object.values(res);

console.log(result)

Upvotes: 3

Related Questions