Функция jQuery, чтобы получить все уникальные элементы из массива?

jQuery.unique позволяет вам получать уникальные элементы массива, но в документах говорится, что функция в основном предназначена для внутреннего использования и работает только с элементами DOM. Другой SO ответ сказал, что unique() Функция работала с числами, но этот вариант использования не обязательно является будущим доказательством, потому что он явно не указан в документации.

Учитывая это, существует ли "стандартная" функция jQuery для доступа только к уникальным значениям - в частности, к примитивам, таким как целые числа - в массиве? (Очевидно, мы можем построить цикл с each() функция, но мы новичок в jQuery и хотели бы знать, есть ли специальная функция jQuery для этого.)

13 ответов

Решение

Ты можешь использовать array.filter вернуть первый элемент каждого отдельного значения

var a = [ 1, 5, 1, 6, 4, 5, 2, 5, 4, 3, 1, 2, 6, 6, 3, 3, 2, 4 ];

var unique = a.filter(function(itm, i, a) {
    return i == a.indexOf(itm);
});

console.log(unique);

Если поддержка IE8 и ниже является основной, не используйте неподдерживаемые filter метод.

Иначе,

if (!Array.prototype.filter) {
    Array.prototype.filter = function(fun, scope) {
        var T = this, A = [], i = 0, itm, L = T.length;
        if (typeof fun == 'function') {
            while(i < L) {
                if (i in T) {
                    itm = T[i];
                    if (fun.call(scope, itm, i, T)) A[A.length] = itm;
                }
                ++i;
            }
        }
        return A;
    }
}

Просто используйте этот код в качестве основы простого плагина JQuery.

$.extend({
    distinct : function(anArray) {
       var result = [];
       $.each(anArray, function(i,v){
           if ($.inArray(v, result) == -1) result.push(v);
       });
       return result;
    }
});

Используйте как так:

$.distinct([0,1,2,2,3]);

Основано на ответе @kennebec, но исправлено для IE8 и ниже с помощью jQuery-обёрток вокруг массива для предоставления отсутствующих функций Array filter а также indexOf:

Оболочка $.makeArray(), возможно, не является абсолютно необходимой, но вы получите странные результаты, если пропустите эту обертку и в противном случае JSON.stringify.

var a = [1,5,1,6,4,5,2,5,4,3,1,2,6,6,3,3,2,4];

// note: jQuery's filter params are opposite of javascript's native implementation :(
var unique = $.makeArray($(a).filter(function(i,itm){ 
    // note: 'index', not 'indexOf'
    return i == $(a).index(itm);
}));

// unique: [1, 5, 6, 4, 2, 3]

Я бы использовал http://underscorejs.org/, который обеспечивает uniq метод, который делает то, что вы хотите.

    // for numbers
    a = [1,3,2,4,5,6,7,8, 1,1,4,5,6]
    $.unique(a)
    [7, 6, 1, 8, 3, 2, 5, 4]

    // for string
    a = ["a", "a", "b"]
    $.unique(a)
    ["b", "a"]

И для элементов dom здесь не нужен пример, я думаю, потому что вы уже это знаете!

Вот ссылка на jsfiddle из живого примера: http://jsfiddle.net/3BtMc/4/

Это решение js1568, модифицированное для работы с общим массивом объектов, например:

 var genericObject=[
        {genProp:'this is a string',randomInt:10,isBoolean:false},
        {genProp:'this is another string',randomInt:20,isBoolean:false},
        {genProp:'this is a string',randomInt:10,isBoolean:true},
        {genProp:'this is another string',randomInt:30,isBoolean:false},
        {genProp:'this is a string',randomInt:40,isBoolean:true},
        {genProp:'i like strings',randomInt:60,isBoolean:true},
        {genProp:'this is a string',randomInt:70,isBoolean:true},
        {genProp:'this string is unique',randomInt:50,isBoolean:true},
        {genProp:'this is a string',randomInt:50,isBoolean:false},
        {genProp:'i like strings',randomInt:70,isBoolean:false}
    ]

Он принимает еще один параметр с именем propertyName, угадайте!:)

  $.extend({
        distinctObj:function(obj,propertyName) {
            var result = [];
            $.each(obj,function(i,v){
                var prop=eval("v."+propertyName);
                if ($.inArray(prop, result) == -1) result.push(prop);
            });
            return result;
        }
    });

Итак, если вам нужно извлечь список уникальных значений для данного свойства, например, значений, используемых для свойства randomInt, используйте это:

$.distinctObj(genericObject,'genProp');

это возвращает массив как это:

["this is a string", "this is another string", "i like strings", "this string is unique"] 

Пройдитесь по массиву и вставьте элементы в хеш, когда вы столкнетесь с ними. Перекрестная ссылка на хеш для каждого нового элемента.

Обратите внимание, что это будет работать ТОЛЬКО для примитивов (строк, чисел, null, undefined, NaN) и нескольких объектов, которые сериализуются в одну и ту же вещь (функции, строки, даты, возможно, массивы в зависимости от содержимого). Хэши в этом конфликтуют, так как все они сериализуются в одну и ту же вещь, например, "[объект объекта]"

Array.prototype.distinct = function(){
   var map = {}, out = [];

   for(var i=0, l=this.length; i<l; i++){
      if(map[this[i]]){ continue; }

      out.push(this[i]);
      map[this[i]] = 1;
   }

   return out;
}

Также нет причин, по которым вы не можете использовать jQuery.unique. Единственное, что мне не нравится в этом, это то, что он разрушает порядок вашего массива. Вот точный код, если вам интересно:

Sizzle.uniqueSort = function(results){
    if ( sortOrder ) {
        hasDuplicate = baseHasDuplicate;
        results.sort(sortOrder);

        if ( hasDuplicate ) {
            for ( var i = 1; i < results.length; i++ ) {
                if ( results[i] === results[i-1] ) {
                    results.splice(i--, 1);
                }
            }
        }
    }

    return results;
};

У Пола Айриша есть метод " Duck Punching" (см. Пример 2), который модифицирует jQuery $.unique() метод для возврата уникальных элементов любого типа:

(function($){
    var _old = $.unique;
    $.unique = function(arr){
        // do the default behavior only if we got an array of elements
        if (!!arr[0].nodeType){
            return _old.apply(this,arguments);
        } else {
            // reduce the array to contain no dupes via grep/inArray
            return $.grep(arr,function(v,k){
                return $.inArray(v,arr) === k;
            });
        }
    };
})(jQuery);
function array_unique(array) {
    var unique = [];
    for ( var i = 0 ; i < array.length ; ++i ) {
        if ( unique.indexOf(array[i]) == -1 )
            unique.push(array[i]);
    }
    return unique;
}

Простое современное решение JavaScript, если вам не нужна поддержка IE (Array.from не поддерживается в IE).

Вы можете использовать комбинацию Set а также Array.from,

var arr = [1, 1, 11, 2, 4, 2, 5, 3, 1];
var set = new Set(arr);
arr = Array.from(set);

console.log(arr);

Set Объект позволяет хранить уникальные значения любого типа, будь то примитивные значения или ссылки на объекты.

Array.from() Метод создает новый экземпляр Array из массива или итеративного объекта.

Вы можете использовать плагин jQuery под названием Array Utilities, чтобы получить массив уникальных элементов. Это можно сделать так:

var distinctArray = $.distinct([1, 2, 2, 3])

diverArray = [1,2,3]

Если кто-то использует http://knockoutjs.com/, попробуйте:

ko.utils.arrayGetDistinctValues()

Кстати, посмотреть на все ko.utils.array* коммунальные услуги.

Начиная с jquery 3.0 вы можете использовать $.uniqueSort(ARRAY)

пример

array = ["1","2","1","2"]
$.uniqueSort(array)
=> ["1", "2"]

Если вам нужна поддержка IE 8 или более ранней версии, для этого можно использовать jQuery.

var a = [1,2,2,3,4,3,5];
var unique = $.grep(a, function (item, index) {
   return index === $.inArray(item, a);
});
Другие вопросы по тегам