Effectively merge fields from one array into two other arrays

Let's say you have 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 a1as a source and add a field idto the elements a2and a3with the corresponding fields namein a1. What is an effective way to achieve this? (Note: โ€œeffectiveโ€ here means โ€œsomething more elegant than loops inside loops inside 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' }
]
+6
source share
5 answers

You can use a Mapname identifier to refer to. 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; }
Run codeHide result
+2
source

.

.

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; }
Hide result
+2
a2.forEach((a2Elem) => a2Elem.id = a1.filter((a1Elem) => a1Elem.name === a2Elem.name)[0].id)
+1

, , :

function combine(mergeInto, base) {
    let indexes = base.map(e => e.name);
    return mergeInto.map(e => ({
        name: e.name,
        id: base[indexes.indexOf(e.name)].id
    }));
}

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' }
]

function combine(mergeInto, base) {
    let indexes = base.map(e => e.name);
    return mergeInto.map(e => ({
        name: e.name,
        id: base[indexes.indexOf(e.name)].id
    }));
}

console.log(combine(a3, a1));
Hide result
+1
source

One-cycle sentence - create hash tableand then merge fields into arrays - demo below:

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

// create a hash table
let hash = a1.reduce(function(p,c){
  p[c.name] = c;
  return p;
},Object.create(null))

// merge the results
function merge(arr) {
  Object.keys(arr).map(function(e){
    arr[e]['id'] = hash[arr[e].name]['id'];
  });
  return arr;
}

console.log(merge(a2), merge(a3));
.as-console-wrapper{top:0;max-height:100%!important;}
Run codeHide result
0
source

All Articles