jQuery.unique允许您获取数组的唯一元素,但是文档说该函数主要供内部使用,并且仅对DOM元素起作用。另一个SO响应说该unique()
函数可以在数字上使用,但是此用例不一定是将来的证明,因为在文档中未明确说明。
鉴于此,是否存在“标准” jQuery函数,用于仅访问数组中的唯一值(特别是整数之类的基元)?(显然,我们可以使用函数构造一个循环each()
,但是我们是jQuery的新手,并且想知道是否为此使用了专用的jQuery函数。)
jQuery.unique允许您获取数组的唯一元素,但是文档说该函数主要供内部使用,并且仅对DOM元素起作用。另一个SO响应说该unique()
函数可以在数字上使用,但是此用例不一定是将来的证明,因为在文档中未明确说明。
鉴于此,是否存在“标准” jQuery函数,用于仅访问数组中的唯一值(特别是整数之类的基元)?(显然,我们可以使用函数构造一个循环each()
,但是我们是jQuery的新手,并且想知道是否为此使用了专用的jQuery函数。)
Answers:
您可以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;
}
}
Array.filter
或Array.indexOf
。请参阅我对此答案的修订,以获取在受jquery支持的浏览器中不会中断的代码。
基于@kennebec的答案,但针对IE8及以下版本,已通过在数组周围使用jQuery包装器提供缺少的Array函数filter
和进行了修复indexOf
:
$ .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]
我将使用underscore.js,它提供了uniq
一种满足您需要的方法。
// 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/
遍历数组,并在遇到它们时将其推入哈希中。交叉引用每个新元素的哈希值。
请注意,这仅适用于原语(字符串,数字,null,未定义,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;
};
Paul Irish有一个“ Duck Punching ”方法(请参见示例2),该$.unique()
方法修改了jQuery的方法以返回任何类型的唯一元素:
(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);
这是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"]
eval("v."+propertyName)
为v[propertyName]
。每次调用时,eval
您都会启动另一个编译器。对于循环,这是非常昂贵的。
如果您不需要IE支持(Array.from
在IE中不支持),则使用普通的JavaScript现代解决方案。
您可以使用Set
和的组合Array.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);
您可以使用名为Array Utilities的jQuery插件来获取唯一项的数组。可以这样完成:
var distinctArray = $.distinct([1, 2, 2, 3])
distantArray = [1,2,3]