Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently merging fields from one array into two other arrays

Let's say you've got three arrays of objects:

let a1 = [
  { id: 1, name: 'foo' },
  { id: 2, name: 'bar' },
  { id: 3, name: 'baz' }
]

let a2 = [
  { name: 'foo' },
  { name: 'bar' }
]

let a3 = [
  { name: 'bar' },
  { name: 'baz' }
]

The goal is to use a1 as a source, and add an id field to the elements of a2 and a3 with corresponding name fields in a1. What is an efficient way of accomplishing this? (Note: 'efficient' here meaning 'something more elegant than loops-within-loops-within-loops'.)

The result should look like this:

a2: [
  { id: 1, name: 'foo' },
  { id: 2, name: 'bar' }
]

a3: [
  { id: 2, name: 'bar' },
  { id: 3, name: 'baz' }
]
like image 965
ken.dunnington Avatar asked Aug 17 '17 14:08

ken.dunnington


People also ask

How to merge two arrays in one array?

To merge elements from one array to another, we must first iterate(loop) through all the array elements. In the loop, we will retrieve each element from an array and insert(using the array push() method) to another array. Now, we can call the merge() function and pass two arrays as the arguments for merging.

How to combine multiple arrays into one JavaScript?

The concat() method concatenates (joins) two or more arrays. The concat() method returns a new array, containing the joined arrays. The concat() method does not change the existing arrays.


2 Answers

You could use a Map for referencing the id of a given name. Then assign.

var a1 = [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }, { id: 3, name: 'baz' }], 
    a2 = [{ name: 'foo' }, { name: 'bar' }],
    a3 = [{ name: 'bar' }, { name: 'baz' }],
    map = new Map(a1.map(o => [o.name, o.id]));
    
[a2, a3].forEach(a => a.forEach(o => o.id = map.get(o.name)));

console.log(a2);
console.log(a3);
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 187
Nina Scholz Avatar answered Oct 06 '22 19:10

Nina Scholz


For an alternative answer, it could be like this.

It doesn't include loops and may be the shortest code in the answers.

const a1 = [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }, { id: 3, name: 'baz' }];
const a2 = [{ name: 'foo' }, { name: 'bar' }];
const a3 = [{ name: 'bar' }, { name: 'baz' }];

let f = x => a1.filter(a => x.some(y => y.name === a.name));

console.log(f(a2));
console.log(f(a3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 41
Gaslan Avatar answered Oct 06 '22 20:10

Gaslan