функция 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 вокруг массива для обеспечения отсутствующих функций массива
filterиindexOf:$.обертка makeArray () может быть не совсем нужна, но вы получите странные результаты, если опустите эту обертку и JSON.в противном случае строжируйте результат.
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]
Я бы использовал подчеркивание.js , который предоставляет метод
uniq, который делает то, что вы хотите.
Пройдитесь по массиву и вставляйте элементы в хэш по мере их появления. Перекрестная ссылка на хэш для каждого нового элемента.
Обратите внимание, что это будет правильно работать только для примитивов (строки, числа, null, undefined, NaN) и нескольких объектов, которые сериализуются в одно и то же (функции, строки, даты, возможно, массивы в зависимости от содержимого). Хэши в этом случае будут сталкиваться, поскольку все они сериализуются на одно и то же, например "[object 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.уникальный. Единственное, что мне в нем не нравится, это то, что он разрушает Порядок вашего массива. Вот точный код для него, если вам интересно:
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; };
// 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/
У Пола Айриша есть метод" 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);
Это решение 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"]
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; }
Для получения массива уникальных элементов можно использовать плагин jQueryArray Utilities . Это можно сделать так:
var distinctArray = $.distinct([1, 2, 2, 3])DistinctArray = [1,2,3]
Если кто-то использует knockoutjs Попробуйте:
ko.utils.arrayGetDistinctValues()Кстати, посмотрите на все
ko.utils.array*утилиты.
Простое современное решение 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()метод создает новый экземпляр массива из массивоподобного или итеративного объекта.
Начиная с jquery 3.0 вы можете использовать
$.uniqueSort(ARRAY)Пример
array = ["1","2","1","2"] $.uniqueSort(array) => ["1", "2"]
Comments