-1

I have two arrays:

var odd = [
    { name : "1", extraProp1 : "propValue1" },
    { name : "3",  extraProp1 : "propValue2"}
];

var even = [
    { name : "1", extraProp2 : "prop1" },
    { name : "2", extraProp2 : "prop2"},
    { name : "4", extraProp2 : "prop3" }
]; 

How do I make a new array that results as:

var result = [{ name : "1", extraProp1 : "propValue1",  extraProp2 : "prop1"}];

They need to be added based on the name property.

EDIT: This is in reference to Merge 2 arrays of objects I have also looked at : How can I merge properties of two JavaScript objects dynamically?

However, when I do this

function merge(a, b, prop){
    var reduced =  a.filter( aitem =>  b.find ( bitem => aitem[prop] === bitem[prop]) );
  return reduced;
}
console.log( "ES6", merge(odd, even, "name") );

It takes property only from one array.

pmehta28
  • 58
  • 4

2 Answers2

1

Indeed, in your attempt you are correctly filtering a, but you have no code that merges two objects.

I would also use a Map for faster lookup than with a nested call of filter:

function merge(a, b, prop) {
    let map = new Map(b.map(o => [o[prop], o]));
    return a.reduce((acc, o) => {
        let match = map.get(o[prop]);
        return match ? acc.concat({ ...o, ...match }) : acc;
    }, []);
}


var odd = [
    { name : "1", extraProp1 : "propValue1" },
    { name : "3",  extraProp1 : "propValue2"}
];

var even = [
    { name : "1", extraProp2 : "prop1" },
    { name : "2", extraProp2 : "prop2"},
    { name : "4", extraProp2 : "prop3" }
]; 

console.log(merge(odd, even, "name"));

The { ...o, ...match } part performs the actual merge of two objects that was missing in your solution.

trincot
  • 317,000
  • 35
  • 244
  • 286
0

The most efficient way I can see (although maybe not leveraging JS predefined functions) is making up a dictionary with the name values as the keys.

You can go through the first array and populate the dictionary. Then you can iterate through the second array and add each element to the dictionary if it doesn't contain the name or merge the objects if it does.

Example:

var odd = [
    { name : "1", extraProp1 : "propValue1" },
    { name : "3",  extraProp1 : "propValue2"}
];

var even = [
    { name : "1", extraProp2 : "prop1" },
    { name : "2", extraProp2 : "prop2"},
    { name : "4", extraProp2 : "prop3" }
]; 

var combinedDictionary = {}

for(let obj of odd) {
  combinedDictionary[obj.name] = obj;
}

for(let obj of even) {
  combinedDictionary[obj.name] = { 
    ...(combinedDictionary[obj.name] || {}),
    ...obj
  };
}

var result = Object.keys(combinedDictionary).map(key => combinedDictionary[key]);

console.log(result);
Cristian Sarghe
  • 782
  • 6
  • 15