Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript - Return only unique values in an array of objects

I have an array of objects where I want to return only the unique objects based on their object Id.

I've tried to loop in the existing array data then find if the element was already add to a newly created array arr which should contain only the unique values, but it didn't work with me and I believe that I am missing something here or there.

Here is the current array :

          [
        {
          "objectId": "WMtwbyhFI6",
          "cuisineNameEn": "Cafe",
          "ordersNo": 20,
          "hidden": false
        },
        {
          "objectId": "QJSNTMpq5F",
          "ordersNo": 24,
          "cuisineNameEn": "Italian",
          "hidden": false
        },
        {
          "objectId": "iLXKswFRGa",
          "ordersNo": 5,
          "cuisineNameEn": "Japanese",
          "hidden": true
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
        {
          "objectId": "QJSNTMpq5F",
          "ordersNo": 24,
          "cuisineNameEn": "Italian",
          "hidden": false
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false,
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
         {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
         {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        }
      ]

However, this is what I want to return :

 [
        {
          "objectId": "WMtwbyhFI6",
          "cuisineNameEn": "Cafe",
          "ordersNo": 20,
          "hidden": false
        },
        {
          "objectId": "iLXKswFRGa",
          "ordersNo": 5,
          "cuisineNameEn": "Japanese",
          "hidden": true
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
        {
          "objectId": "QJSNTMpq5F",
          "ordersNo": 24,
          "cuisineNameEn": "Italian",
          "hidden": false
        }
      ]

I've tried the following:

 var arr = [];
  data.forEach((el)=>{
  if (arr.indexOf(el.objectId) === -1) {
    arr.push(el)
  }
 })

However, it didn't work.

like image 925
Hamza L. Avatar asked Dec 03 '22 11:12

Hamza L.


2 Answers

Use the reduce() method:

data.reduce((acc, x) =>
   acc.concat(acc.find(y => y.ordersNo === x.ordersNo) ? [] : [x])
 , []);

reduce goes through the array, and for each element it calls the provided function with accumulator (the return value of the previous call) and the current element. concat adds the current element to the accumulator if it doesn't exist there yet. find checks if the current element exists in the accumulator by comparing the ordersNo properties.

Demo:

const data =           [
        {
          "objectId": "WMtwbyhFI6",
          "cuisineNameEn": "Cafe",
          "ordersNo": 20,
          "hidden": false
        },
        {
          "objectId": "QJSNTMpq5F",
          "ordersNo": 24,
          "cuisineNameEn": "Italian",
          "hidden": false
        },
        {
          "objectId": "iLXKswFRGa",
          "ordersNo": 5,
          "cuisineNameEn": "Japanese",
          "hidden": true
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
        {
          "objectId": "QJSNTMpq5F",
          "ordersNo": 24,
          "cuisineNameEn": "Italian",
          "hidden": false
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false,
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
         {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
         {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        },
        {
          "objectId": "Db0MeihpJE",
          "ordersNo": 6,
          "cuisineNameEn": "Fast Food",
          "hidden": false
        }
      ];
 
 console.log(data.reduce((acc, x) =>
   acc.concat(acc.find(y => y.ordersNo === x.ordersNo) ? [] : [x])
 , []));
like image 63
Michał Perłakowski Avatar answered Dec 06 '22 12:12

Michał Perłakowski


You may filter the array and use a Set of ids to check for dupes:

const result = array.filter( (hash => obj => !(hash.has(obj.objectId) || hash.add(obj.objectId) && false))(new Set));
like image 40
Jonas Wilms Avatar answered Dec 06 '22 11:12

Jonas Wilms