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

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

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

【问题讨论】:

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

标签: javascript jquery jquery-selectors


【解决方案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]);
              

              【讨论】:

                猜你喜欢
                • 2014-12-17
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-06-30
                • 1970-01-01
                • 2018-09-09
                • 2023-02-16
                相关资源
                最近更新 更多