Exploring How to Identify and Eliminate Duplicate Objects in 2 Arrays

I'm working with two arrays of objects in JavaScript and my goal is to compare, merge the contents, and sort by id. Specifically, I want the final sorted array to include all objects from the first array, as well as any objects from the second array that have an id not present in the first.

While the code provided below seems to achieve this (without sorting), I believe there must be a more concise way to accomplish this task, especially leveraging ES6 features. I suspect that using a Set might be the key, but I'm unsure about the implementation details.

    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},
    ];
    
    // The resulting cars1 should contain all cars from cars1 and 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;
    }

Answer №1

One efficient approach with linear time complexity would involve creating a Set of the ids from cars1, then combining cars1 and filtered cars2 into an output array by checking if the id in the current car from cars2 is present 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);

You can also sort the combined array based on id:

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);

Answer №2

To achieve the desired outcome, utilize concat, filter, and map.

var vehicles1 = [ {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 vehicles2 = [ {id: 3, make: "Kia", model: "Optima", year: 2001}, {id: 4, make: "Nissan", model: "Sentra", year: 1982}, {id: 2, make: "Toyota", model: "Corolla", year: 1980}, ];

// Merging unique cars from vehicles2 with all cars from vehicles1
let ids = vehicles1.map(c => c.id);
vehicles1 = vehicles1.concat(vehicles2.filter(({id}) => !ids.includes(id)))
console.log(vehicles1);

Answer №3

Combine two arrays, assign each array item to a map with their corresponding ids, then generate an array from the map values.

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},
];

cars = cars1.concat(cars2);
let foo = new Map();
for(const c of cars){
  foo.set(c.id, c);
}
let final = [...foo.values()]
console.log(final)

Answer №4

If you're looking to extract information from a collection of cars, one way to do it is by using a Map. This allows you to access specific items within the map, such as individual cars.

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 }],
    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 }],
    result = Array
        .from(
            [...cars1, ...cars2]
                .reduce((m, c) => m.set(c.id, m.get(c.id) || c), new Map)
                .values()
        )
        .sort((a, b) => a.id - b.id);

console.log(result);

Answer №5

To combine two arrays of objects and remove duplicates based on a specific key, you can utilize Object.values(), .concat(), and .reduce() methods:

let 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},
];

let 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},
];

let merge = (arr1, arr2) => Object.values(
    arr1.concat(arr2).reduce((result, current) => (result[current.id] = result[current.id] || current, result), {})
).sort((a, b) => a.id - b.id);

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

Answer №6

If we assume that the IDs should all be unique, this solution should do the trick:

const combineArrays = (arr1, arr2) => 
{
    const result = arr1.slice(0);
    arr2.forEach((el) => 
    { 
        if (getIndexByAttribute(arr1, 'id', el.id) < 0)
            result.push(el); 
    });
    return result;
};

const getIndexByAttribute = (array, attr, value) => {
    for(let i = 0; i < array.length; i += 1) {
        if(array[i][attr] === value) {
            return i;
        }
    }
    return -1;
}

However, based on your examples "cars1" and "cars2", you may require object comparison. You can refer to Object comparison in JavaScript [duplicate] for more information.

Answer №7

To solve this problem, one strategy is to utilize the concat() method along with the elements from cars2 that do not already exist in cars1. This can be achieved by checking for existing ids using the find() function. Afterwards, the resulting array can be sorted using the sort() function:

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},
];

let res = cars1
    .concat(cars2.filter(({id}) => !cars1.find(x => x.id === id)))
    .sort((a, b) => a.id - b.id);

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to confirm the presence of strings within an array?

For instance: var array = ["apple", "banana", "cherry", "date", "elderberry", "fig"]; What is the best way to determine if "apple", "banana", and "cherry" are present in the array? I attempted using the indexOf() method but struggled to check for multip ...

Steps for integrating external components into Laravel 5.3 with VueJs Routes

I am currently working with Laravel 5.3 and utilizing the built-in VueJs components. At this point, my goal is to implement routes into my project. I have attempted to use the following code, but unfortunately, it is not functioning as expected. const No ...

Grunt Watch is currently not executing any tasks for JavaScript or CSS

I'm encountering an issue with my grunt-watch not running for the JS or CSS configurations The Grunt file is located in a 'tools' folder. The project structure is as follows: -index.html -js -css -tools --package.json --node modules --grun ...

Creating and accessing a temporary binary file using Node Js

Challenge I have been working on integrating the Google Text To Speech (TTS) service to save a generated binary audio file to Google Cloud Storage (GCS). Considering that saving a local binary file in Firebase's Cloud Functions environment may not b ...

Can Javascript be used to obtain someone's UDID?

Is it feasible to retrieve individuals' UDIDs when they visit your website? If this is achievable, could you recommend a helpful tutorial for me to follow? ...

Utilizing Data Binding in D3.js

Why is the text "Hello" not appearing five times on the page as expected? index.html <html> <head> <title>Data Binding</title> </head> <body> <h1>D3.js</h1> <script src="https://d3js.o ...

Trouble with Google Interactive Charts failing to load after UpdatePanel refresh

Desperately seeking assistance! I have spent countless hours researching this issue but have hit a dead end. My dilemma involves using the Google Interactive Charts API within an UpdatePanel to dynamically update data based on dropdown selection changes. H ...

Learning how to toggle default snippet keywords on and off based on specific scenarios within the Angular Ace Editor

Within the Ace editor, I have incorporated custom snippets alongside the default ones. However, there are certain scenarios where I would like to exclusively display the custom snippets and hide the default ones. Is there a way to disable or conceal the ...

Ways to evaluate and contrast two JSON values in JavaScript by their key names?

I am dealing with two JSON arrays that look like this: array1=[{a:1,b:2,c:3,d:4}] & array2=[{a:2,b:5,c:3,d:4}] Is there a way to determine which key in array2 has the same value as one of the keys in array1? For example, in array 1, key b has a value ...

How to use AJAX to retrieve data from a JSON file hosted on an external URL?

Is it possible to extract data from a JSON file that belongs to an external source such as ABS, a company that provides weather information? The weather data is stored in a JSON File. Why am I unable to access this information and save it? & ...

What is the best way to arrange an array using AngularJs or Javascript?

When a user makes a selection, I want to sort and display an array in alphabetical order. Specifically, when we render data from the backend, I would like to display the fullName in alphabetical order. The $scope.selectedControlOwner is the ng-click event ...

Steps to eliminate the x icon from the text box that appears automatically in Internet Explorer

I'm currently working with a UI5 text box that includes a built-in option for clearing the text using a 'X' button. However, I've noticed that in Internet Explorer, an additional default cross mark is being added alongside the UI5 cros ...

Displaying events in the all-day section can be achieved by setting the defaultView of fullCalendar.js to 'agendaDay'

Trying to use fullCalendar.js with defaultView set to agendaDay, and pulling events from mysql as JSON. However, I'm encountering an ERROR where it displays the events in the 'all-Day' section. Here are some of the solutions I attempted: e ...

What is the best way to combine two arrays of negative numbers into a single array?

I am trying to merge negative numbers from two arrays. Here is my approach: I add elements to an array, and then attempt to merge elements that are less than zero into a new array. This is the code snippet I have been working on: int main() { int arr ...

Angular does not have the capability to automatically update itself

I have developed an angular project that includes a navigation bar. I would like the navigation bar to automatically update when users log in. I tried using ng-show and ng-hide to control it, but unfortunately, it doesn't seem to work. Can someone hel ...

What is the correct way to encapsulate a socket.io socket for optimal performance?

In my node.js server application, this code is currently executing: io.sockets.on('connection', function (socket) { var c = new Client(socket, Tools.GenerateID()); waitingClients.push(c); allClients.push(c); if (waitingClients ...

Unable to control the content within the Repeater DIV

When working inside a repeater's ItemTemplate, I encountered an issue where only the first image/div toggled visibility when the toggle button/link was pressed. The images are dynamically loaded from the database and the toggle function seems to only ...

How can data be sent to the server in JavaScript/AJAX without including headers?

JavaScript - Is it possible to transfer data to the server backend without using headers? ...

Having trouble retrieving prices using an npm package

There is a more effective way to retrieve prices using the npm package, node-binance-api, rather than relying on the "coin" variable that I am currently struggling with. If anyone could assist me in finding a better solution or the optimal method for fetch ...

Tips for concealing a div using an article until it is activated by hovering over it

I am looking to incorporate a sleek sliding animation on an article that reveals more information in a div upon mouseover. A great example of this can be seen on where clicking at the top right corner triggers the "Show Modern Dev Ad" feature. Below is m ...