Find distinct elements in an array of objects

Imagine you have an array filled with different objects:

var itemsArray = [
  {name: "apple", color: "red", weight: "100g"},
  {name: "banana", color: "yellow", weight: "120g"},
  {name: "apple", color: "red", weight: "100g"},
  {name: "banana", color: "yellow", weight: "120g"},
  {name: "orange", color: "orange", weight: "150g"},
  {name: "grape", color: "purple", weight: "80g"},
  {name: "orange", color: "orange", weight: "150g"}
];

We want to filter this array to remove duplicate objects:

var itemsArray = [
  {name: "apple", color: "red", weight: "100g"},
  {name: "banana", color: "yellow", weight: "120g"},
  {name: "orange", color: "orange", weight: "150g"},
  {name: "grape", color: "purple", weight: "80g"}
];

While filtering arrays of plain strings is simple:

itemsArray.filter(function (value, index, self) { 
    return self.indexOf(value) === index;
}

It doesn't work for objects. We need to compare all properties to achieve this. Perhaps a deep comparison method is required?

Answer №1

If all your objects share the same keys, you have the option to utilize either lodash's or underscore's _.findWhere function:

This function performs a deep comparison between each element in the collection and the source object, returning the first element that has equivalent property values.

var arr = [
  {a: "foo", b: "bar", c: "baz" },
  {a: "foo", b: "bar", c: "qux" },
  {a: "foo", b: "bar", c: "baz" },
  {a: "foo", b: "bar", c: "qux" },
  {a: "bar", b: "foo", c: "qux" },
  {a: "bar", b: "qux", c: "foo" },
  {a: "bar", b: "foo", c: "qux" }
];

function uniqueObjects(arr) {
  var u = [];
  arr.forEach(function(obj) {
    if (!_.findWhere(u, obj)) {
      u.push(obj);
    }
  });
  return u
}

document.getElementById('result').innerHTML = JSON.stringify(uniqueObjects(arr),null,2);
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.7.0/lodash.min.js"></script>
<pre id='result'></pre>

If not, you can perform a deep comparison using _.matches in both directions:

var arr = [
  {a: "foo", b: "bar", c: "baz" },
  {a: "foo", b: "bar", c: "qux" },
  {a: "foo", b: "bar", c: "baz" },
  {a: "foo", b: "bar", c: "qux" },
  {a: "bar", b: "foo", c: "qux" },
  {a: "bar", b: "qux", c: "foo" },
  {a: "bar", b: "foo", c: "qux" },
  // Missing property
  {a: "foo", b: "bar" },
  // Ordering
  {a: "foo", c: "qux" },
  {c: "qux", a: "foo" }
];

function uniqueObjects(arr) {
  var u = [];
  arr.forEach(function(obj) {
    if (!u.filter(deepCompare(obj)).length) {
      u.push(obj);
    }
  });
  return u;
}

function deepCompare(obj) {
  return function(source) {
    return _.matches(obj)(source) && _.matches(source)(obj);
  };
}

document.getElementById('result').innerHTML = JSON.stringify(uniqueObjects(arr),null,2);
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.7.0/lodash.min.js"></script>
<pre id='result'></pre>

Answer №2

My comment outlines the approach I've taken.

var array = [
  {c: "baz", a: "foo", b: "bar" },
  {c: "qux", a: "foo", b: "bar" },
  {c: "baz", b: "bar", a: "foo" },
  {c: "qux", b: "bar", a: "foo" },
  {a: "bar", c: "qux", b: "foo" },
  {a: "bar", c: "foo", b: "qux" },
  {a: "bar", b: "foo", c: "qux" }
];

var updatedArray = array.map(function (val) {
    var res = [];
    var keys = Object.keys(val).sort();

    for (var i = 0; i < keys.length; i++) {
        res.push(val[keys[i]]);
    }
    return res.join('');
});

for (var i = (updatedArray.length - 1); i >= 0; i--) {
    if (updatedArray.indexOf(updatedArray[i]) !== i) {
        array.splice(i, 1);
    }
}


alert(JSON.stringify(array));

Answer №3

Utilize lodash library for removing duplicates in arrays! Check out the documentation here

By using SameValueZero for equality comparisons, lodash creates a version of an array without any duplicate elements, keeping only the first occurrence of each. If the array is sorted, providing true for isSorted can result in a faster search algorithm. You can also pass an iteratee function which will be invoked for each element in the array to determine uniqueness. The iteratee function is bound to thisArg and takes three arguments: (value, index, array).

To include lodash in your HTML, use the following script tag:

<script src="bower_components/lodash/lodash.js"></script>

Next, in your controller, you can use the following code snippet:

var filteredArray = _.uniq(arr, function(item, key, a) { 
    return item.a;
});

For a live example, check out this jsFiddle link: http://jsfiddle.net/8xp3o7b3/3/

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

What is the best way to retrieve the value from a textfield in one module and use it in a

How can I access the value of a textField in another module within React.js without importing the entire textfield component? What is the most effective approach to get access to the value variable in a different module? Below is a sample functional textF ...

Django and its compatibility with modal windows

I have developed a Django website that includes multiple items in a "for" loop. I need to delete a specific item by opening a modal window and passing the post ID (referred to as "get_post_id") to the modal window. However, I want the modal window to exist ...

Unable to switch between navigation items and icons

Currently, I am in the process of learning vanilla JavaScript and I'm trying to incorporate a navigation feature similar to when the hamburger icon is clicked. However, I have encountered an issue where I cannot toggle the hamburger icon to change it ...

Transforming dates from JSON and showcasing them on a DataTable

I'm facing an issue with my local JSON file where the dates are being rendered in a DataTable as /Date(1350028800000)/ (10/12/2012). I came across this thread which talks about converting the date format, but I need help figuring out how to implement ...

Retrieve all records from the query and store them in an array, then output a singular value

Retrieve all rows from the database based on a specific query and return a single value Query the database for data //---------------------------------------------------------------------- $result = mysql_query("SELECT * FROM $tableName"); query ...

During operational hours, an Ajax request may cause interruptions to the website's functionality

Having an issue with a large ajax request: I am querying a PHP file that makes some cURL requests, taking 15-20 seconds to complete and then returning JSON on my webpage. It's a standard ajax request, but I found a strange bug. While the ajax query i ...

Upon triggering a GET request to the URL "http://localhost:3000/search", a "404 (Not Found)" error response was received. Interestingly

Can Someone assist me please? I'm having trouble creating a website similar to YouTube and encountering the following error: GET http://localhost:3000/search 404 (Not Found) Uncaught (in promise) Error: Request failed with status code 404 at createEr ...

AngularJS redirection to a different state by utilizing a URL

When I need to direct a user to a specific state, typically I would use the following code: $state.go('state_name'); $state.transitionTo('state_name'); This method usually takes users to /state_name. However, there is one particular s ...

Error: Attempting to access 'scrollTop' property of null object in Material UI library

After updating from MUI-4 to MUI-5, I encountered this error. Can anyone provide assistance? ...

Refresh the table every couple of seconds

I need to regularly update a table every two to three seconds or in real-time if possible. The current method I tried caused the table to flash constantly, making it difficult to read and straining on the eyes. Would jQuery and Ajax solve this issue? How c ...

Can a function be called when using ng-options with AngularJS select?

Here is some HTML code <select ng-model="selectedMarker" ng-options="shape.text for shape in Selects('shapes')"> </select> And below is the JavaScript code angular.module('todo', ['ionic']) . ...

Creating a Dual Y-Axis Chart with Two Sets of Data in chart.js

I utilized the chart.js library to write the following code snippet that generated the output shown below. My primary concern is how to effectively manage the labels on the horizontal axis in this scenario. CODE <!DOCTYPE html> <html lang="en"& ...

managing the reloading of pages and navigating back and forth in the browser

In my project, I am using react and next.js to make API requests from a search bar and display a list of movies on the homepage. Each search result redirects me to a different page that shows detailed data related to the selected movie. However, the issue ...

How to iterate over the request body in Node.js using Express?

When I send a request with data in the form of an array of objects: [ {id: "1"}, {id: "2"}, {id: "3"} ] I am utilizing JSON.stringify() and my req.body ends up looking like this: { '{"id":"1"} ...

The curly braces in AngularJS are not resolving as expected, however, the ng-bind directive is functioning properly

I'm currently working on a Django application and utilizing AngularJS for my frontend. I have a straightforward piece of code that looks like this: <div class="vert-carousel" ng-controller="PrizeController"> <div class="gallery-cell" n ...

Exploring the seamless integration of Material UI slider with chart js

Looking for guidance on syncing Material UI slider with chart js? I'm working on a line chart and hoping to have the x-axis value highlighted with tooltip as I slide the Material UI slider. ...

extract elements from dataset

Attempting to splice an array but encountering index issues var kode_pelayanan = []; function deleteKodePelayanan(index){ kode_pelayanan.splice(index, 1); console.log(kode_pelayanan); } Experimented in the console with an array for kode_pelayanan ...

Access another key within an object

Here's a code snippet from my module: exports.yeah = { hallo: { shine: "was", yum: this.hallo.shine } } In the above code, I'm attempting to reference the shine property in yum: this.hallo.shine However, when I run the script, ...

The proper formatting of JSON strings in AWS using GraphQL

I'm currently working on creating an object value to be passed into DynamoDB using AWS AppSync and GraphQL. I'm almost there, but I'm facing challenges with nested JSON structures. Let's imagine I have an array: let officers = [{" ...

What is the best way to access and display the innerText of elements that have been removed using console

When I call the updateCartTotal() function, my goal is to display in the console the items that have been removed from the shopping cart. Every time I click on the remove button, I want it to show the item and the price. However, instead of displaying the ...