2011-03-21 118 views
64

jQuery.unique可以讓你獲得數組中唯一的元素,但是文檔說這個函數主要是爲了內部使用而且只對DOM元素進行操作。另一個SO響應說,unique()函數處理數字,但這個用例不一定是未來的證明,因爲它沒有在文檔中明確說明。jQuery函數從數組中獲取所有獨特的元素?

鑑於此,是否存在一個「標準」jQuery函數,用於訪問數組中的唯一值(特別是像整數一樣的基元)? (顯然,我們可以構造與each()功能的循環,但我們是新來的jQuery,並想知道是否有這個專用的jQuery的功能。)

+1

*** @ Future_Readers - 在檢查其他人之前,請參閱Rubyrider的答案*** – gibberish 2015-03-01 18:13:45

+1

@Future_Readers - 檢查Rubyrider的答案時,請注意您可能會看到使用它的意外結果 - 這不是一個安全或可靠的解決方案。 – Yuck 2016-02-29 20:29:41

回答

106

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

警告:在IE8及以下版本中,上述代碼BREAKS不支持「Array.filter」或「Array.indexOf」。查看我對此答案的修訂,以查看在jQuery支持的瀏覽器中沒有中斷的代碼。 – Dennis 2011-12-06 15:49:21

+0

支持從IE9開始,有關更多信息,請訪問https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter – Organiccat 2013-04-30 15:44:48

+1

或使用許多EcmaScript 5墊片之一,例如[this one由Kriskowal](https://github.com/kriskowal/es5-shim) – superjos 2013-08-08 17:11:57

6

走的陣列,推動項目到一個哈希,你遇到他們。交叉引用每個新元素的散列。

請注意,這將只適用於基元(字符串,數字,空,未定義,NaN)和一些序列化爲相同的東西(函數,字符串,日期,可能數組取決於內容)的對象。當它們都序列化成相同的東西時,這裏的哈希將會相互碰撞,例如, 「[object Object]」

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

我會用underscore.js,它提供了一個uniq方法你想要做什麼。

+1

現在鏈接被破壞。檢查[此鏈接](http://underscorejs.org/#uniq) – 2016-03-04 10:08:17

43

只需使用此代碼作爲簡單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]); 
+0

偉大的擴展! – Wen 2014-02-05 00:11:11

13

基於@肯納貝克的答案,但固定IE8及以下使用陣列周圍jQuery的包裝提供缺陣功能filterindexOf

$ .makeArray()包裝可能不是絕對需要的,但如果您省略此包裝和JSON,則會得到奇怪的結果。

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] 
+0

似乎沒有工作了,更改過濾器爲:return i == $ .inArray(itm,a); – Shadaez 2015-03-29 22:00:38

5

保羅愛爾蘭有一個「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); 
1

您可以使用jQuery插件叫做Array Utilities得到一系列獨特的物品。 這是可以做到這樣的:

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

distinctArray = [1,2,3]

+0

這個聯合函數也支持任意數量的數組,這個包[jquery-array-utilities](https://libraries.io/bower/jquery-array-utilities)也可以使用[bower](https:/ /bower.io)。我想添加一個免責聲明,我最初做的插件:) – 2016-11-28 21:32:24

4

這是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"] 
+0

我真的很想知道我寫了什麼值得-1。 – Dariozzo 2014-01-31 16:08:24

+1

我沒有downvote(我剛看到這個答案),但我建議你將'eval(「v。」+ propertyName)''改成'v [propertyName]'。每次你調用'eval'時,你都會啓動另一個編譯器。對於一個循環來說,這非常昂貴。 – Shaz 2014-09-16 14:17:15

1

如果有人使用knockoutjs嘗試:

ko.utils.arrayGetDistinctValues() 

順便說一句,看看所有ko.utils.array*公用事業。

6
// 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/

+6

但文檔說$ .unique()* only *適用於DOM元素! 「對DOM元素進行排序,刪除重複項。請注意,這隻適用於DOM元素數組,而不是字符串或數字。」 - http://api.jquery.com/jquery.unique/ – Kat 2015-03-15 02:33:54

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

在jQuery 3.0,你可以用$.uniqueSort(ARRAY)

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

實際上,'uniqueSort'與jquery 2中的'unique'是一樣的。它旨在排序對象而不是字符串。 – Mike 2017-06-09 02:01:42

1

普通的JavaScript現代化的解決方案,如果你不」 t需要IE支持(IE不支持Array.from)。可以使用SetArray.from的組合。

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

 
console.log(arr);

Set對象允許您存儲任何類型的唯一值,無論是原始值或對象引用。

Array.from()方法從類數組或者可迭代對象中創建一個新的數組實例。