Удалите дубликаты из массива объектов в JavaScript

У меня есть объект, который содержит массив объектов.

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

Я задаюсь вопросом, что является лучшим методом для удаления дублирующихся объектов из массива. Так, например, things.thing стал бы...

{place:"here",name:"stuff"},
{place:"there",name:"morestuff"}
304
задан Donald Duck 27 November 2017 в 12:30
поделиться

3 ответа

Примитивным методом будет:

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]);
142
ответ дан 23 November 2019 в 01:21
поделиться

Если вы можете подождать, чтобы удалить дубликаты до завершения всех добавлений, типичный подход состоит в том, чтобы сначала отсортировать массив, а затем удалить дубликаты. Сортировка позволяет избежать подхода N * N, когда вы просматриваете массив для каждого элемента.

Функция «удаления дубликатов» обычно называется unique или uniq . Некоторые существующие реализации могут комбинировать эти два шага, например, uniq прототипа

В этом сообщении есть несколько идей, которые стоит попробовать (и некоторых, которых следует избегать :-)) , если в вашей библиотеке их еще нет ! Лично я считаю, что это самый простой:

    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;
    }
22
ответ дан 23 November 2019 в 01:21
поделиться

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.

ES5 answer

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 (!arr.some(function(item) { return thingsEqual(item, val); })) { arr.push(val); } } } function thingsEqual(thing1, thing2) { return thing1.place === thing2.place && thing1.name === thing2.name; } var things = [ {place:"here",name:"stuff"}, {place:"there",name:"morestuff"}, {place:"there",name:"morestuff"} ]; removeDuplicates(things, thingsEqual); console.log(things);

Original ES3 answer

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);
14
ответ дан 23 November 2019 в 01:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: