JQuery.unique для массива строк
Описание jQuery.unique()
гласит:
Сортирует массив элементов DOM на месте с удалением дубликатов. Обратите внимание, что это работает только с массивами элементов DOM, а не строк или чисел.
С учетом описания, может ли кто-нибудь объяснить, почему работает код ниже?
<div></div>
<div></div>
var arr = ['foo', 'bar', 'bar'];
$.each(arr, function(i, value){
$('div').eq(0).append(value + ' ');
});
$.each($.unique(arr), function(i, value){
$('div').eq(1).append(value + ' ');
});
http://jsfiddle.net/essX2/
Спасибо
Изменить: Возможное решение:
function unique(arr) {
var i,
len = arr.length,
out = [],
obj = { };
for (i = 0; i < len; i++) {
obj[arr[i]] = 0;
}
for (i in obj) {
out.push(i);
}
return out;
};
Ответы
Ответ 1
Он может работать с строками массива и т.д., но он не был предназначен для использования...
Обратите внимание, что код для unique()
скрывается в Sizzle как uniqueSort
: источник github
В то время как некоторый из этого дополнительного кода может показаться, что он будет работать на любом массиве, обратите внимание на sortOrder
как определено здесь. Он делает много дополнительной работы, чтобы поместить вещи в "порядок документов" - следовательно, в документации указано, что он должен использоваться только для массивов элементов DOM.
Ответ 2
Хотя он работает, вы должны, вероятно, учитывать описание функции. Если создатели говорят, что он не предназначен для фильтрации массивов чего-либо другого, кроме элементов dom, вам, вероятно, следует их слушать.
Кроме того, эту функциональность довольно легко воспроизвести:
function unique(array){
return array.filter(function(el, index, arr) {
return index === arr.indexOf(el);
});
}
(демонстрационная страница)
Обновление:
Чтобы этот код работал во всех браузерах (включая ie7, который не поддерживает некоторые функции массива, такие как indexOf
или filter
), перепишите с помощью jquery-функций:
- используйте
$.grep
вместо Array.filter
- используйте
$.inArray
вместо Array.indexOf
Теперь, как выглядит переведенный код:
function unique(array) {
return $.grep(array, function(el, index) {
return index === $.inArray(el, array);
});
}
(демонстрационная страница)
Ответ 3
Я знаю уникальные работы с DOM, но это WORKS на массивах int:
$.unique(arr.sort());
Ответ 4
Если вы не используете jQuery, используйте Set из ES6.
var arr = ['foo', 'bar', 'bar'];
Array.from(new Set(arr)); // #=> ["foo", "bar"]
Работа для Firefox 45, Safari 9 и Chrome 49.
Ответ 5
$.unique
удалит дублирующие элементы DOM, а не идентичные элементы DOM. Когда вы пытаетесь использовать его в строках, вы получаете непредсказуемое поведение, и сортировка будет (возможно) неудачной.
Это функция, предназначенная для внутреннего использования только jQuery и не будет полезна для простых смертных, таких как вы и я.
Ответ 6
Существует быстрый способ расширения функции 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);
// in use..
var arr = ['first',7,true,2,7,true,'last','last'];
$.unique(arr); // ["first", 7, true, 2, "last"]
var arr = [1,2,3,4,5,4,3,2,1];
$.unique(arr); // [1, 2, 3, 4, 5]
http://www.paulirish.com/2010/duck-punching-with-jquery/ - пример # 2
Ответ 7
$. unique будет удалять только дублирующий элемент DOM, если вам нужен массив:
var result=[] ;
$.each([12,1,2,4,3,1,4,3,3,2,111],
function(i,e){ if($.inArray(e,result)===-1) result.push(e) ;});
result;