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;