我有一组数字,我需要确保它们是唯一的。我在互联网上找到了下面的代码片段,它工作得很好,直到数组中有一个零。我在Stack Overflow上找到了另一个脚本,看起来几乎与它完全一样,但它不会失败。

所以为了帮助我学习,有人能帮我确定原型脚本哪里出错吗?

Array.prototype.getUnique = function() {
 var o = {}, a = [], i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 for (e in o) {a.push (e)};
 return a;
}

重复问题的更多答案:

从JS数组中删除重复值

类似的问题:

获取数组中的所有非唯一值(即:重复/多次出现)


当前回答

使用JavaScript 1.6/ECMAScript 5,您可以通过以下方式使用Array的本机筛选器方法来获得具有唯一值的数组:

仅函数唯一(值、索引、自身){return self.indexOf(value)==索引;}//用法示例:var a=['a',1,'a',2,'1'];var unique=a.filter(仅唯一);console.log(唯一);//[阿',1,2,'1']

本机方法筛选器将循环遍历数组,并只保留那些传递给定回调函数的条目。

如果给定值是第一个出现,则仅唯一检查。如果没有,它必须是副本,并且不会被复制。

这个解决方案不需要任何额外的库,如jQuery或prototype.js。

它也适用于具有混合值类型的数组。

对于不支持本机方法filter和indexOf的旧浏览器(<ie9),您可以在MDN文档中找到filter和indexOf的解决方法。

如果要保留值的最后一次出现,只需将indexOf替换为lastIndexOf。

使用ES6,这可以缩短为:

//用法示例:var myArray=['a',1,'a',2,'1'];var unique=myArray.filter((v,i,a)=>a.indexOf(v)==i);console.log(唯一);//唯一的是['a',1,2,'1']

感谢卡米洛·马丁的评论提示。

ES6有一个本地对象Set来存储唯一值。要获得具有唯一值的数组,现在可以执行以下操作:

var myArray=['a',1,'a',2,'1'];let unique=[…new Set(myArray)];console.log(唯一);//唯一的是['a',1,2,'1']

Set的构造函数接受一个可迭代的对象,如Array,而扩展运算符。。。将集合转换回数组。感谢Lukas Liese的评论提示。

其他回答

魔术

a.filter(e=>!(t[e]=e in t)) 

O(n)性能-我们假设您的阵列位于a中,且t={}。此处解释(+Jeppe impr.)

让unique=(a,t={})=>a.filter(e=>!(t〔e〕=e in t));//使用全局t的“单机”版本://a1.过滤器((t={},e=>!(t[e]=e in t));//测试数据设a1=[5,6,0,4,9,2,3,5,0,3,4,1,5,4,9];设a2=[[2,17],[2,17]、[2,17]、[1,12]、[5,9]、[1,12]、[6,2],[1,12]];设a3=[“迈克”、“亚当”、“马特”、“南希”、“亚当斯”、“珍妮”、“南茜”、“卡尔”];//结果console.log(JSON.stringify(唯一(a1)))console.log(JSON.stringify(唯一(a2)))console.log(JSON.stringify(唯一(a3)))

我不知道为什么加布里埃尔·西尔韦拉会这样写函数,但一种更简单的形式对我同样适用,而且没有缩小:

Array.prototype.unique = function() {
  return this.filter(function(value, index, array) {
    return array.indexOf(value, index + 1) < 0;
  });
};

或在CoffeeScript中:

Array.prototype.unique = ->
  this.filter( (value, index, array) ->
    array.indexOf(value, index + 1) < 0
  )

您可以使用Ramda.js(一个功能性javascript库)来执行此操作:

var unique=R.uniq([1,2,1,3,1,4])console.log(唯一)<script src=“https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js“></script>

One Liner,纯JavaScript

使用ES6语法

list=list.filter((x,i,a)=>a.indexOf(x)==i)

x --> item in array
i --> index of item
a --> array reference, (in this case "list")

使用ES5语法

list = list.filter(function (x, i, a) { 
    return a.indexOf(x) == i; 
});

浏览器兼容性:IE9+

我知道这个问题已经解决了。。。但是没有人提到linq的javascript实现。然后就可以使用.dispect()方法了,这使得代码非常容易阅读。

var Linq = require('linq-es2015');
var distinctValues =  Linq.asEnumerable(testValues)
            .Select(x)
            .distinct()
            .toArray();

var测试值=[1,2,3,4,5,6,7,8,9,0,1,2,1];var distinctValues=可枚举.asEnumerable(测试值).dispect().toArray();console.log(distinctValues);<script src=“https://npmcdn.com/linq-es5/dist/linq.js“></script>