jQuery.unique对一个字符串数组的应用

46
根据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;
};

3
我猜在这里它只是“偶然奏效”,但不能指望它在文档未描述的其他情况下也能奏效。 - m90
1
@Johan,它显示它并不是为其他用途设计的,而且可能会失败。如果您正在寻找更强大的东西,您考虑使用underscore.js了吗? - m90
1
一个数组不是字符串 - 还是吗?请参阅Paul Irish在此处的文章中有关unique的部分:http://paulirish.com/2010/duck-punching-with-jquery/ unique有一个修改。 - Jay Blanchard
@Johan 我会采用你修改后的答案。 - vol7ron
@vol7ron 好的。是的,这是我的线程问题的解决方案,因为$.unique不适用于那种情况。 - Johan
显示剩余9条评论
9个回答

105

虽然它可以工作,但您应该考虑函数描述。如果创建者说它不是为过滤除dom元素以外的任何其他东西而设计的,则应该听取他们的意见。
此外,这个功能很容易被复制:

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

(演示页面)

更新:

为了让这段代码在所有浏览器中都能够工作(包括不支持某些数组功能的ie7,例如indexOffilter),下面是使用jquery功能重写的代码:

现在这里是 翻译后 的代码应该是什么样子:

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

演示页面


感谢提供代码片段。如果我没记错的话,在ie7中indexOf不能用于数组。我需要它在那里也能正常工作。我已经更新了我的问题,并提供了另一个可能的解决方案。 - Johan
1
你可以使用jQuery的inArray代替indexOf。请查看更新。 - gion_13
@Jonah 你是对的..我又更新了我的答案,因为我也掉进了同样的陷阱。IE7及以下版本也不支持Array.filter :))。请查看更新。 - gion_13
这里使用的是宽松相等 ==。lodash 使用严格相等 ===,而 PHP 则采用先转换为字符串的混合形式。我可以建议添加一个可选的 strict 参数吗? - zamnuts
好的,你可以使用严格相等运算符(===),但在这些情况下,两个操作数始终都是数字,所以不会有任何显著的区别,但无论如何,感谢您的反馈。我将更新答案以使用严格相等,因为...那才是我两年前应该编写代码的方式 :) - gion_13

23

可能适用于字符串数组等,但并没有为此设计...

注意,unique()的代码隐藏在Sizzle中,名为uniqueSortgithub源代码

虽然其中一些额外的代码似乎可以适用于任何数组,但请注意 sortOrder, 在此定义。 它需要做很多额外的工作来按“文档顺序”排列元素-因此文档说明指出它只应用于DOM元素的数组。


注意:从jQuery 3.0开始,jQuery.unique()已被弃用,并且只是jQuery.uniqueSort()的别名。请改用该方法。 - thdoan

15

我知道unique函数可以用于DOM,但是它也可以处理int数组:

$.unique(arr.sort());

9
如果不使用jQuery限制,请考虑使用ES6的Set。
var arr = ['foo', 'bar', 'bar'];
Array.from(new Set(arr)); // #=> ["foo", "bar"]

适用于Firefox 45、Safari 9和Chrome 49。


4

$.unique函数将会移除重复的DOM元素,而不是相同的DOM元素。如果你尝试在字符串上使用它,那么你将得到不可预测的行为,并且排序将(很可能)失败。

这个函数只是jQuery内部使用的,对于像我们这样的凡人来说并没有什么用处。


我想说的是$.unique明确文档说明了它只能接受一个由DOM元素组成的数组。任何试图将其用于由字符串组成的数组都是技术上错误的,并且会导致未记录和不可预测的行为。 - Blazemonger

3

有一种快速的方法可以扩展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]

Duck Punching with jQuery - 第二个示例


0

好的,所以如果没有Sizzle,jQuery的简写将会受到赞赏!

基于gion_13答案,我刚刚重写了一个本地数组实现。

Array.prototype.unique = function() { 
    let _array = this;
    return $.grep(_array, function(el, index) {
        return index === $.inArray(el, _array);
    });
};

编辑为一致的 ES 短...

Array.prototype.unique=function(){let _array=this;return $.grep(_array,function(el, index){return index===$.inArray(el,_array);});};

在这种情况下测试已完成

var A = ['1', 'green', true, 'blue', 1, (!false), 'toto', 'green', (!!0) ];

console.log( A );
// Array(9) [ "1", "green", true, "blue", 1, true, "toto", "green", false ]

console.log( A.unique() );
//Array(7) [ "1", "green", true, "blue", 1, "toto", false ]

关于 evclid 的注意事项,$.unique(arr.sort()); 可以正常工作,但我们会失去顺序(:


0

$.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;

0
var array=['a','b','c','a'];

    function unique(array)
    {
    var unique_arr=[];
    array.forEach(function(i,e)
    {
    if(unique_arr.indexOf(i)===-1) unique_arr.push(i);
    });
    return unique_arr;
    }
    console.log(unique(array));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接