jQuery函数从数组中获取所有唯一元素?

Posted

技术标签:

【中文标题】jQuery函数从数组中获取所有唯一元素?【英文标题】:jQuery function to get all unique elements from an array? 【发布时间】:2011-07-19 21:24:35 【问题描述】:

jQuery.unique 可让您获取数组的唯一元素,但文档说该函数主要供内部使用并且仅对 DOM 元素进行操作。另一个 SO 响应说 unique() 函数适用于数字,但这个用例不一定是未来的证明,因为它没有在文档中明确说明。

鉴于此,是否有一个“标准”jQuery 函数用于仅访问数组中的唯一值(特别是整数等基元)? (显然,我们可以使用each() 函数构造一个循环,但我们是 jQuery 新手,想知道是否有专门的 jQuery 函数。)

【问题讨论】:

@Future_Readers - 在检查 Rubyrider 的答案时,请注意使用它可能会看到意想不到的结果 - 这不是一个安全或可靠的解决方案。 【参考方案1】:

如果需要支持 IE 8 或更早版本,可以使用 jQuery 来完成。

var a = [1,2,2,3,4,3,5];
var unique = $.grep(a, function (item, index) 
   return index === $.inArray(item, a);
);

【讨论】:

【参考方案2】:

如果您不需要 IE 支持,则使用纯 javascript 现代解决方案(IE 不支持Array.from)。

您可以使用SetArray.from 的组合。

const arr = [1, 1, 11, 2, 4, 2, 5, 3, 1];
const set = new Set(arr);
const uniqueArr = Array.from(set);

console.log(uniqueArr);

Set 对象允许您存储任何类型的唯一值,无论是原始值还是对象引用。

Array.from() 方法从类数组或可迭代对象创建一个新的 Array 实例。

还可以将Array.from() 替换为扩展运算符。

const arr = [1, 1, 11, 2, 4, 2, 5, 3, 1];
const set = new Set(arr);
const uniqueArr = [...set];

console.log(uniqueArr);

【讨论】:

var arr = [1, 1, 11, 2, 4, 2, 5, 3, 1]; [...新设置(arr)]; @AshishSinghRawat 谢谢,添加了扩展运算符语法的选项。【参考方案3】:

您可以使用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;
    

【讨论】:

警告:上述代码在 IE8 及更低版本中中断,它们不支持 Array.filterArray.indexOf。有关在 jquery 支持的浏览器中不中断的代码,请参阅我对此答案的修订。 支持从 IE9 开始,更多信息请访问developer.mozilla.org/en-US/docs/JavaScript/Reference/… 或使用众多 EcmaScript 5 垫片之一,例如 this one by Kriskowal @cwolves 的回答应该是被接受的。这个答案以及几乎所有其他答案都在 O(n^2) 时间内运行,如果您在大数组上尝试它会非常非常慢。 简单的答案,太棒了。【参考方案4】:

我会使用underscore.js,它提供了一个uniq 方法,可以满足您的需求。

【讨论】:

【参考方案5】:

从 jquery 3.0 开始,您可以使用 $.uniqueSort(ARRAY)

例子

array = ["1","2","1","2"]
$.uniqueSort(array)
=> ["1", "2"]

【讨论】:

其实uniqueSort和jquery 2中的unique是一样的,是用来排序对象而不是字符串的。【参考方案6】:
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;

【讨论】:

【参考方案7】:

这是 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"] 

【讨论】:

我真的很想知道我写了什么值得-1。 我没有投反对票(我刚刚看到这个答案),但我建议您将eval("v."+propertyName) 更改为v[propertyName]。每次调用eval 时,都会启动另一个编译器。对于一个循环,这是相当昂贵的。【参考方案8】:
    // 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/

【讨论】:

但是文档说 $.unique() only 适用于 DOM 元素! “对 DOM 元素数组进行排序,删除重复项。请注意,这仅适用于 DOM 元素数组,不适用于字符串或数字。” -- api.jquery.com/jquery.unique【参考方案9】:

遍历数组并在遇到项目时将它们推入散列。交叉引用每个新元素的哈希。

请注意,这仅适用于原语(字符串、数字、null、未定义、NaN)和一些序列化为同一事物的对象(函数、字符串、日期,可能是取决于内容的数组)。其中的哈希会发生冲突,因为它们都序列化为同一事物,例如“[对象对象]”

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.unique。我唯一不喜欢的是它破坏了数组的顺序。如果您有兴趣,这是它的确切代码:

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

【讨论】:

【参考方案10】:

如果有人在使用knockoutjs 试试:

ko.utils.arrayGetDistinctValues()

顺便说一句,看看所有ko.utils.array* 实用程序。

【讨论】:

【参考方案11】:

您可以使用名为 Array Utilities 的 jQuery 插件来获取一组独特的项目。 可以这样做:

var distinctArray = $.distinct([1, 2, 2, 3])

distinctArray = [1,2,3]

【讨论】:

这个联合函数还支持任意数量的数组,这个包jquery-array-utilities也可以使用bower安装。我想添加一个我最初制作插件的免责声明 :)【参考方案12】:

Paul Irish 有一个“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);

【讨论】:

【参考方案13】:

基于@kennebec 的回答,但通过在数组周围使用 jQuery 包装器以提供缺少的数组函数 filterindexOf,已针对 IE8 及以下版本进行了修复:

$.makeArray() 包装器可能不是绝对需要的,但如果你省略这个包装器和 JSON.stringify 否则你会得到奇怪的结果。

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]

【讨论】:

好像不行了,把过滤器改成:return i == $.inArray(itm, a);【参考方案14】:

只需将此代码用作简单 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]);

【讨论】:

以上是关于jQuery函数从数组中获取所有唯一元素?的主要内容,如果未能解决你的问题,请参考以下文章

从 jQuery 集合中获取每个元素的属性值,放入数组中

使用 Javascript/jQuery 从 HTML 元素中获取所有属性

在Jquery中获取元素的唯一选择器

如何从 jquery 对象映射中过滤唯一的数据属性值

从plist中的一组元素中获取唯一元素

jquery怎么从数组移除元素