4

here is a sample example where there are two arrays and we have a merge() to which we pass the arrays. the merge() should return the merged array such that it should merge the objects which have same name.

let arr1 = [
  {
    name: "Person1",
    age: 20
  },
  {
    name: "Person2",
    age: 30
  }
]


let arr2 = [
  {
    name: "Person1",
    email: "[email protected]"
  },
  {
    name: "Person3",
    age: 25
  }
]


arr3 = merge(arr1, arr2)

output : 
arr3 should be : 
[
 {
    name: "Person1",
    age: 20,
    email: "[email protected]"
  },
   {
    name: "Person2",
    age: 30
  },
   {
    name: "Person3",
    age: 25
  }
]
8
  • 2
    Does this answer your question? How to merge two arrays in JavaScript and de-duplicate items Commented Feb 9, 2022 at 11:13
  • 1
    @Shatsuki That question is about merging arrays of strings, this question is about merging an array of objects, where some of the objects themselves might need to be merged. Commented Feb 9, 2022 at 11:14
  • You may break down the problem into smaller sub-problems. First identify the unique names from both arrays. Then, iterate through the names and pull the corresponding props from both arrays to construct your target array. Will try to post an answer, if possible. Commented Feb 9, 2022 at 11:15
  • Can you please provide your attempt so far for the merge function? What specifically are you having problems with? Commented Feb 9, 2022 at 11:16
  • 1
    name similar ... similar or the same? the two words are not synonymous Commented Feb 9, 2022 at 11:18

7 Answers 7

3

You could take an object as hash table for keeping track of merged objects with same name and return only the values from the hash table.

const
    merge = (...arrays) => {
        const merged = {};
        
        arrays.forEach(data =>
            data.forEach(o => Object.assign(merged[o.name] ??= {}, o))
        );
        
        return Object.values(merged);
    },
    array1 = [{ name: "Person1", age: 20 }, { name: "Person2", age: 30 }],
    array2 = [{name: "Person1", email: "[email protected]" }, { name: "Person3", age: 25 }],
    result = merge(array1, array2);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the answer, would you please help me to understand what ??= operator stands for in Object.assign(merged[o.name] ??= {}, o)?
it is a logical nullish assignment ??=. that means, if the lhs (left hand side) is null or undefined, the rhs gets assigned.
2

You can use lodash for that

let arr1 = [
  {
    name: "Person1",
    age: 20
  },
  {
    name: "Person2",
    age: 30
  }
]


let arr2 = [
  {
    name: "Person1",
    email: "[email protected]"
  },
  {
    name: "Person3",
    age: 25
  }
]


arr3 = _.merge(_.keyBy(arr1, 'name'), _.keyBy(arr2, 'name'));

console.log(arr3)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

Comments

0

The map part covers every item in arr1, so you can add it as is or merge with the ones both in arr1 and arr2. Then you need a final pass to add those that are in arr2 but not in arr1

let arr1 = [
  {
    name: "Person1",
    age: 20
  },
  {
    name: "Person2",
    age: 30
  }
]


let arr2 = [
  {
    name: "Person1",
    email: "[email protected]"
  },
  {
    name: "Person3",
    age: 25
  }
]

const merge = (a1,a2) => {

return a1.map( (x) => {
  const y = a2.find( item => x.name === item.name);
  if (y) {
    return Object.assign({},x,y);
  } else
    return x
}).concat(a2.filter(item => a1.every( x => x.name !== item.name)));




}

arr3 = merge(arr1, arr2)

console.log(arr3)

Comments

0

We can convert the arrays into objects for better time complexity and merge them using a spread operator and generate the array at the end.

let arr1 = [
  {
    name: "Person1",
    age: 20
  },
  {
    name: "Person2",
    age: 30
  }
]


let arr2 = [
  {
    name: "Person1",
    email: "[email protected]"
  },
  {
    name: "Person3",
    age: 25
  }
]
function merge(arr1, arr2){
  const merged_dict = {}
  const r_arr = []
  const arr = [...arr1,...arr2]
  arr.forEach(ele => {
    if(merged_dict[ele.name]){
      merged_dict[ele.name] = {...merged_dict[ele.name],...ele};
    }
    else{
      merged_dict[ele.name] = ele;
    }
  });
  for(let key in merged_dict){
    r_arr.push(merged_dict[key])
  }
  return r_arr
}

arr3 = merge(arr1, arr2)
console.log(arr3)

Comments

0

Try this :

let arr1 = [{
    name: "Person1",
    age: 20
}, {
    name: "Person2",
    age: 30
}];
let arr2 = [{
    name: "Person1",
    email: "[email protected]"
}, {
    name: "Person3",
    age: 25
}];
function copy(source, destination) {
    for (let prop in source) {
        destination[prop] = source[prop];
    }
}
function merge(arr1, arr2) {
    let newArray = [];
    for (let i = 0, obj1; obj1 = arr1[i]; ++i) {
        let obj = {};
        copy(obj1, obj);
        for (let j = 0, obj2; obj2 = arr2[j]; ++j) {
            if (obj1.name === obj2.name) {
                copy(obj2, obj);
            }
        }
        newArray.push(obj);
    }
    for (let i = 0, obj2; obj2 = arr2[i]; ++i) {
        let here = false;
        for (let j = 0, obj1; obj1 = arr1[j]; ++j) {
            if (obj1.name === obj2.name) {
                here = true;
            }
        }
        if (!here) {
            newArray.push(obj2);
        }
    }
    return newArray;
}
let arr3 = merge(arr1, arr2);
console.log(arr3);

Comments

0

    let a = [
               {
                name: "Person15",
                age: 29
               },
               {
              name: "Person20",
          age: 39
         }
        ];;

            let b =  [
               {
                name: "Person1",
                age: 20
               },
               {
              name: "Person2",
          age: 30
         }
        ];

            // b diff a
            let resultA = b.filter(
              elm =>
                !a
                  .map(elm => JSON.stringify(elm)).includes(JSON.stringify(elm)),
            );

            // a diff b
            let resultB = a.filter(
              elm =>
                !b
                  .map(elm => JSON.stringify(elm)).includes(JSON.stringify(elm)),
            );

            // show merge
            
            const mergedArray = [ ...resultA, ...resultB ]


            const mergedArrays = [ ...b, ...mergedArray ]

            let newData = [
              ...new Map(mergedArrays.map(item => [item.id, item])).values(),
            ];
            console.log(newData);

Comments

-1
  let arr1 = [
  {
   name: "Person1",
   age: 20
},
 {
 name: "Person2",
 age: 30
 }
]
 
let arr2 = [
 {
  name: "Person1",
  email: "[email protected]"
},
 {
   name: "Person3",
   age: 25
  }
] 


var arr3 = [...arr1,...arr2]

1 Comment

with this we will have 4 objects instead of 3 output : 0: {name: 'Person1', age: 20} 1: {name: 'Person2', age: 30} 2: {name: 'Person1', email: '[email protected]'} 3: {name: 'Person3', age: 25}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.