简体   繁体   English

Javascript - 仅返回对象数组中的唯一值

[英]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.我有一个对象数组,我只想根据它们的对象 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.我尝试在现有数组data循环,然后查找元素是否已添加到新创建的数组arr ,该数组应仅包含唯一值,但它对我不起作用,我相信我在这里遗漏了一些东西或那里。

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.然而,它没有用。

Use the reduce() method :使用reduce()方法

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. reduce遍历数组,对于每个元素,它使用累加器(前一次调用的返回值)和当前元素调用提供的函数。 concat adds the current element to the accumulator if it doesn't exist there yet.如果当前元素尚不存在,则concat会将当前元素添加到累加器中。 find checks if the current element exists in the accumulator by comparing the ordersNo properties. find通过比较ordersNo属性来检查当前元素是否存在于累加器中。

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]) , []));

您可以filter数组并使用一组 id 来检查欺骗:

const result = array.filter( (hash => obj => !(hash.has(obj.objectId) || hash.add(obj.objectId) && false))(new Set));

You can use array#reduce and create an object with objectId as the key and the object as the values.您可以使用array#reduce并创建一个以objectId为键、以对象为值的对象。 Once, you have your object, extract all values to get the unique objects using Object.values() .一旦有了对象,使用Object.values()提取所有值以获取唯一对象。

 var 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 } ], result = Object.values(data.reduce((r,o) => (r[o.objectId] = o, r),{})); console.log(result);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

You should try with filter and Set :您应该尝试使用 filter 和 Set :

result = (function () { // we use an IIFE to isolate everything
    var uniqIds = new Set(); // Set only accepts unique values
    return list.filter(item => { // Array filter returns a new array based on result of callback passed in parameter
        if(!uniqIds.has(item.objectId)) {
            uniqIds.add(item.objectId);
            return true;
        } else {
            return false;
        }
    });
}());

indexOf() won't work to check similar objects or check properties inside objects. indexOf()无法检查类似的对象或检查对象内部的属性。 It will only work with object references that are the same它仅适用于相同的对象引用

Can use a hashmap object that stores the common property as keys.可以使用将公共属性存储为键的 hashmap 对象。 Following uses this argument of filter for the hashmap以下使用this filter参数作为哈希图

 const res = data.filter(o => !this[o.objectId] && (this[o.objectId]=true), {}); console.log(res);
 <script> 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 } ]; </script>

You can also use this simple solution您也可以使用这个简单的解决方案

 function uniqueObjectsArr(array, uniqueValue) { var obj = {}, uniqueArr = []; array.forEach(element => { obj[element[uniqueValue]] = element; }); for (var key in obj) { if (obj.hasOwnProperty(key)) { uniqueArr.push(obj[key]); } } return uniqueArr; } myData = uniqueObjectsArr(myData, "objectId"); console.log(myData);
 <script> myData = [ { "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 } ] </script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM