Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare 2 Arrays of Objects and Remove Duplicates

I have 2 arrays of objects in JavaScript and would like to compare and merge the contents and sort the results by id. Specifically, the resulting sorted array should contain all objects from the 1st array, plus all objects from the 2nd array that have an id that's not in the 1st.

The following code seems to work (minus the sorting). But there must be a better, more succinct way to do this, particularly with features from ES6. I assume using a Set is the way to go, but not sure exactly how to implement.

    var cars1 = [
        {id: 2, make: "Honda", model: "Civic", year: 2001},
        {id: 1, make: "Ford",  model: "F150",  year: 2002},
        {id: 3, make: "Chevy", model: "Tahoe", year: 2003},
    ];
    
    var cars2 = [
        {id: 3, make: "Kia",    model: "Optima",  year: 2001},
        {id: 4, make: "Nissan", model: "Sentra",  year: 1982},
        {id: 2, make: "Toyota", model: "Corolla", year: 1980},
    ];
    
    // Resulting cars1 contains all cars from cars1 plus unique cars from cars2
    cars1 = removeDuplicates(cars2);
    console.log(cars1);
    
    function removeDuplicates(cars2){
        for (entry in cars2) {
            var keep = true;
    
            for (c in cars1) {
                if (cars1[c].id === cars2[entry].id) {
                    keep = false;
                }
            }
    
            if (keep) {
                cars1.push({
                    id:cars2[entry].id,
                    make:cars2[entry].make,
                    model:cars2[entry].model,
                    year:cars2[entry].year
                })
            }
        }
        return cars1;
    }
like image 889
Woodchuck Avatar asked Jan 11 '19 07:01

Woodchuck


People also ask

How do I remove duplicates in two arrays?

Example 1: Using concat() and for Loop In the above program, the two array elements are merged together and the duplicate elements are removed. Here, The two arrays are merged using the concat() method. The for...of loop is used to loop through all the elements of arr .

How do I compare two arrays of arrays?

Using Arrays. equals(array1, array2) methods − This method iterates over each value of an array and compare using equals method. Using Arrays. deepEquals(array1, array2) methods − This method iterates over each value of an array and deep compare using any overridden equals method.


2 Answers

One option with O(N) complexity would be to make a Set of the ids in cars1, then spread cars1 and a filtered cars2 into the ouput array, with the filter testing whether the id in the car being iterated over in cars2 is included in the Set:

var cars1 = [
    {id: 2, make: "Honda", model: "Civic", year: 2001},
    {id: 1, make: "Ford",  model: "F150",  year: 2002},
    {id: 3, make: "Chevy", model: "Tahoe", year: 2003},
];

var cars2 = [
    {id: 3, make: "Kia",    model: "Optima",  year: 2001},
    {id: 4, make: "Nissan", model: "Sentra",  year: 1982},
    {id: 2, make: "Toyota", model: "Corolla", year: 1980},
];
const cars1IDs = new Set(cars1.map(({ id }) => id));
const combined = [
  ...cars1,
  ...cars2.filter(({ id }) => !cars1IDs.has(id))
];
console.log(combined);

To sort as well:

combined.sort(({ id: aId }, {id: bId }) => aId - bId);

var cars1 = [
    {id: 2, make: "Honda", model: "Civic", year: 2001},
    {id: 1, make: "Ford",  model: "F150",  year: 2002},
    {id: 3, make: "Chevy", model: "Tahoe", year: 2003},
];

var cars2 = [
    {id: 3, make: "Kia",    model: "Optima",  year: 2001},
    {id: 4, make: "Nissan", model: "Sentra",  year: 1982},
    {id: 2, make: "Toyota", model: "Corolla", year: 1980},
];
const cars1IDs = new Set(cars1.map(({ id }) => id));
const combined = [
  ...cars1,
  ...cars2.filter(({ id }) => !cars1IDs.has(id))
];
combined.sort(({ id: aId }, {id: bId }) => aId - bId);
console.log(combined);
like image 93
CertainPerformance Avatar answered Oct 01 '22 13:10

CertainPerformance


You could use concat, filter and map.

var cars1 = [ {id: 2, make: "Honda", model: "Civic", year: 2001}, {id: 1, make: "Ford", model: "F150", year: 2002}, {id: 3, make: "Chevy", model: "Tahoe", year: 2003}, ];

var cars2 = [ {id: 3, make: "Kia", model: "Optima", year: 2001}, {id: 4, make: "Nissan", model: "Sentra", year: 1982}, {id: 2, make: "Toyota", model: "Corolla", year: 1980}, ];

// Resulting cars1 contains all cars from cars1 plus unique cars from cars2
let ids = cars1.map(c => c.id);
cars1 = cars1.concat(cars2.filter(({id}) => !ids.includes(id)))
console.log(cars1);
like image 28
Mihai Alexandru-Ionut Avatar answered Oct 01 '22 15:10

Mihai Alexandru-Ionut