it-swarm.com.ru

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

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

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

66
Crashalot

Вы можете использовать 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;
    }
}
115
kennebec

Просто используйте этот код в качестве основы простого плагина 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]);
46
js1568

Основано на ответе @ 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]
13
Dennis

Я бы использовал underscore.js , который предоставляет метод uniq, который делает то, что вы хотите.

9
lawnsea
    // 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/

6
Rubyrider

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

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

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;
};
6
Mark Kahn
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;
}
5
jaggedsoft

это решение 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"] 
5
Dariozzo

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

(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);
5
Mottie

Простое современное решение 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 из массива или повторяемого объекта.

1
Vadim Ovchinnikov

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

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

diverArray = [1,2,3]

1
Kristian Abrahamsen

Если кто-то использует knockoutjs try:

ko.utils.arrayGetDistinctValues()

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

1
Torbjörn Nomell

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

Пример

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