天天看點

從JavaScript中的對象數組中删除重複項

本文翻譯自:Remove duplicates from an array of objects in JavaScript

I have an object that contains an array of objects.

我有一個包含對象數組的對象。
things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});
           

I'm wondering what is the best method to remove duplicate objects from an array.

我想知道什麼是從數組中删除重複對象的最佳方法。

So for example, things.thing would become...

舉例來說,事物……東西将變成……
{place:"here",name:"stuff"},
{place:"there",name:"morestuff"}
           

#1樓

參考:https://stackoom.com/question/9JGJ/從JavaScript中的對象數組中删除重複項

#2樓

A primitive method would be:

一種原始方法是:
var obj = {};

for ( var i=0, len=things.thing.length; i < len; i++ )
    obj[things.thing[i]['place']] = things.thing[i];

things.thing = new Array();
for ( var key in obj )
    things.thing.push(obj[key]);
           

#3樓

This is a generic way of doing this: you pass in a function that tests whether two elements of an array are considered equal.

這是執行此操作的通用方法:傳遞一個函數來測試數組的兩個元素是否相等。

In this case, it compares the values of the

name

and

place

properties of the two objects being compared.

在這種情況下,它将比較兩個要比較的對象的

name

place

屬性的值。

ES5 answer

ES5答案

Original ES3 answer

ES3原始答案
function arrayContains(arr, val, equals) {
    var i = arr.length;
    while (i--) {
        if ( equals(arr[i], val) ) {
            return true;
        }
    }
    return false;
}

function removeDuplicates(arr, equals) {
    var originalArr = arr.slice(0);
    var i, len, j, val;
    arr.length = 0;

    for (i = 0, len = originalArr.length; i < len; ++i) {
        val = originalArr[i];
        if (!arrayContains(arr, val, equals)) {
            arr.push(val);
        }
    }
}

function thingsEqual(thing1, thing2) {
    return thing1.place === thing2.place
        && thing1.name === thing2.name;
}

removeDuplicates(things.thing, thingsEqual);
           

#4樓

If you can wait to eliminate the duplicates until after all the additions, the typical approach is to first sort the array and then eliminate duplicates.

如果您要等到所有添加之後才消除重複項,那麼典型的方法是先對數組排序,然後消除重複項。

The sorting avoids the N * N approach of scanning the array for each element as you walk through them.

排序避免了在周遊每個元素時使用N * N方法掃描數組中每個元素的方法。

The "eliminate duplicates" function is usually called unique or uniq .

“消除重複項”功能通常稱為unique或uniq 。

Some existing implementations may combine the two steps, eg, prototype's uniq

一些現有的實作可以将兩個步驟結合起來,例如, 原型的uniq

This post has few ideas to try (and some to avoid :-) ) if your library doesn't already have one !

這篇文章有一些想法,嘗試(和一些避免:-)) 如果你的庫已經沒有之一 !

Personally I find this one the most straight forward:

我個人認為這是最直接的方法:
function unique(a){
        a.sort();
        for(var i = 1; i < a.length; ){
            if(a[i-1] == a[i]){
                a.splice(i, 1);
            } else {
                i++;
            }
        }
        return a;
    }  

    // Provide your own comparison
    function unique(a, compareFunc){
        a.sort( compareFunc );
        for(var i = 1; i < a.length; ){
            if( compareFunc(a[i-1], a[i]) === 0){
                a.splice(i, 1);
            } else {
                i++;
            }
        }
        return a;
    }
           

#5樓

If you can use Javascript libraries such as underscore or lodash, I recommend having a look at

_.uniq

function in their libraries.

如果可以使用下劃線或lodash之類的Javascript庫,建議您檢視它們庫中的

_.uniq

函數。

From

lodash

:

lodash

_.uniq(array, [isSorted=false], [callback=_.identity], [thisArg])
           

Basically, you pass in the array that in here is an object literal and you pass in the attribute that you want to remove duplicates with in the original data array, like this:

基本上,您傳入的數組是此處的對象文字,然後傳入要删除原始資料數組中重複項的屬性,如下所示:
var data = [{'name': 'Amir', 'surname': 'Rahnama'}, {'name': 'Amir', 'surname': 'Stevens'}];
var non_duplidated_data = _.uniq(data, 'name'); 
           

UPDATE : Lodash now has introduced a

.uniqBy

as well.

更新 :Lodash現在也引入了

.uniqBy

#6樓

Another option would be to create a custom indexOf function, which compares the values of your chosen property for each object and wrap this in a reduce function.

另一個選擇是建立一個自定義indexOf函數,該函數将比較每個對象所選屬性的值并将其包裝在reduce函數中。
var uniq = redundant_array.reduce(function(a,b){
      function indexOfProperty (a, b){
          for (var i=0;i<a.length;i++){
              if(a[i].property == b.property){
                   return i;
               }
          }
         return -1;
      }

      if (indexOfProperty(a,b) < 0 ) a.push(b);
        return a;
    },[]);
           

繼續閱讀