jQuery.unique en una matriz de cadenas

La descripción de jQuery.unique() dice:

Ordena una matriz de elementos DOM, en su lugar, con los duplicados eliminados. Tenga en cuenta que esto solo funciona en arreglos de elementos DOM, no en cadenas o números.

Con la descripción en mente, ¿alguien puede explicar por qué funciona el siguiente código?

 

 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/

Gracias

Editar: Posible solución:

 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; }; 

Puede funcionar en cadenas de matriz, etc., pero no ha sido diseñado para ese uso …

Observe que el código para unique() se esconde en Sizzle como uniqueSort : github source

Si bien es posible que parte de ese código adicional parezca funcionar en cualquier arreglo, preste mucha atención a sortOrder como se define aquí . Hace mucho trabajo adicional para poner las cosas en “orden de documentos”, de ahí que la documentación indique que solo debe usarse en matrices de elementos DOM.

Aunque funciona, probablemente debería tener en cuenta la descripción de la función. Si los creadores dicen que no está diseñado para filtrar matrices de otra cosa que no sean elementos dom, probablemente deberías escucharlos.
Además, esta funcionalidad es bastante fácil de reproducir:

 function unique(array){ return array.filter(function(el, index, arr) { return index === arr.indexOf(el); }); } 

( página de demostración )

Actualizar:

Para que este código funcione en todos los navegadores (incluido ie7 que no admite algunas características de la matriz, como indexOf o filter ), aquí hay una reescritura usando las funcionalidades de jquery:

  • use $.grep lugar de Array.filter
  • use $.inArray lugar de Array.indexOf

Ahora esta es la forma en que debería verse el código traducido :

 function unique(array) { return $.grep(array, function(el, index) { return index === $.inArray(el, array); }); } 

( página de demostración )

Si no se limita a usar jQuery, considere usar Set from ES6.

 var arr = ['foo', 'bar', 'bar']; Array.from(new Set(arr)); // #=> ["foo", "bar"] 

Trabajando para Firefox 45, Safari 9 y Chrome 49.

Sé que las obras únicas con DOM pero esto FUNCIONA en matrices de int:

 $.unique(arr.sort()); 

$.unique eliminará los elementos DOM duplicados , no los elementos DOM idénticos . Cuando intenta usarlo en cadenas, obtiene un comportamiento impredecible y la clasificación (probablemente) fallará.

Es una función diseñada solo para uso interno por jQuery, y no será útil para meros mortales como tú y yo.

Hay una forma rápida de extender la función jQuery.unique () para trabajar en matrices que contienen elementos de cualquier tipo.

 (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/ – ejemplo # 2

$ .unique solo eliminará el elemento DOM duplicado, si lo necesita para el conjunto:

 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;