Br0ke138
Br0ke138

Reputation: 19

Combine two arrays of objects by key and push values of second array into new array inside first array

I need a result Array which containts the data of both arrays. If the name is the same, add the value of the second array into an array of the first array. What would be the best way to do this?

var array1 = [
  {name: "name1", type: "type"},
  {name: "name2", type: "type"},
  {name: "name3", type: "type"}
]

var array2 = [
  {name: "name1", value: "value1"},
  {name: "name2", value: "value2"},
  {name: "name2", value: "value3"},
  {name: "name2", value: "value4"}
]

var result = [
  {name: "name1", type: "type", values: [
    "value1"
  ]},
  {name: "name2", type: "type", values: [
    "value2",
    "value3",
    "value4"
  ]},
  {name: "name3", type: "type", values:[]}
]

Upvotes: 1

Views: 68

Answers (4)

Jake
Jake

Reputation: 1429

Here is my approach (note that it modifies array1):

var array1 = [
  {name: "name1", type: "type"},
  {name: "name2", type: "type"},
  {name: "name3", type: "type"}
]

var array2 = [
  {name: "name1", value: "value1"},
  {name: "name2", value: "value2"},
  {name: "name2", value: "value3"},
  {name: "name2", value: "value4"}
]

var result = array1.map(item => {
  item.values = array2
    .filter(x => x.name === item.name)
    .map(x => x.value)
    
  return item
})

console.log(result)

Upvotes: 1

Haohong Xu
Haohong Xu

Reputation: 1

You can use Array.prototype.map(), Array.prototype.filter() and ES6 spread operator to do the trick.

var array1 = [
  {name: "name1", type: "type"},
  {name: "name2", type: "type"},
  {name: "name3", type: "type"}
]

var array2 = [
  {name: "name1", value: "value1"},
  {name: "name2", value: "value2"},
  {name: "name2", value: "value3"},
  {name: "name2", value: "value4"}
]

let result = array1.map(item1 => ({
  ...item1,
  values: array2
    .filter(item2 => item2.name === item1.name)
    .map(item2 => item2.value)
}));

console.log(result);

Upvotes: 0

dhilt
dhilt

Reputation: 20744

A single-line solution based on ES6 Array.prototype map and reduce methods and on spread opearator:

const result = array1.map(a1 => ({...a1, values: 
  array2.reduce((r, a2) => a2.name === a1.name ? [...r, a2.value] : r, [])
}));

And the version without spread operator but with ES6 Object.assign:

const result = array1.map(a1 => Object.assign({}, a1, { values: 
  array2.reduce((r, a2) => a2.name === a1.name ? r.push(a2.value) && r : r, [])
}));

Upvotes: 0

Ecstabis
Ecstabis

Reputation: 454

This gives you everything except the empty array where name is name3 , you could easily add this by looping over every element of array1 and add an empty array.

var array1 = [
  {name: "name1", type: "type"},
  {name: "name2", type: "type"},
  {name: "name3", type: "type"}
];

var array2 = [
  {name: "name1", value: "value1"},
  {name: "name2", value: "value2"},
  {name: "name2", value: "value3"},
  {name: "name2", value: "value4"}
];

for(let i = 0; i < array2.length; i++){
  let data = array2[i];
  for(let j = 0; j < array1.length; j++){
    if(array1[j].name == array2[i].name){
      if(array1[j].value == undefined) array1[j].value = [];
      array1[j].value.push(array2[i].value);

    }
  }
}

console.log(array1);

Upvotes: 0

Related Questions