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
)。
您可以使用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);
【讨论】:
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.filter
或 Array.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 包装器以提供缺少的数组函数 filter
和 indexOf
,已针对 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函数从数组中获取所有唯一元素?的主要内容,如果未能解决你的问题,请参考以下文章