我有一组数字,我需要确保它们是唯一的。我在互联网上找到了下面的代码片段,它工作得很好,直到数组中有一个零。我在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数组中删除重复值

类似的问题:

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


当前回答

看来我们已经失去了拉斐尔的答案,这是几年来公认的答案。如果没有混合类型数组,这是(至少在2017年)性能最好的解决方案:

Array.prototype.getUnique = function(){
    var u = {}, a = [];
    for (var i = 0, l = this.length; i < l; ++i) {
        if (u.hasOwnProperty(this[i])) {
            continue;
        }
        a.push(this[i]);
        u[this[i]] = 1;
    }
return a;
}

如果您有混合类型数组,则可以序列化哈希键:

Array.prototype.getUnique = function() {
    var hash = {}, result = [], key; 
    for ( var i = 0, l = this.length; i < l; ++i ) {
        key = JSON.stringify(this[i]);
        if ( !hash.hasOwnProperty(key) ) {
            hash[key] = true;
            result.push(this[i]);
        }
    }
    return result;
}

其他回答

您也可以使用underscore.js。

控制台日志(_.uniq([1,2,1,3,1,4]));<script src=“http://underscorejs.org/underscore-min.js“></script>

其将返回:

[1, 2, 3, 4]

您也可以使用sugar.js:

[1,2,2,3,1].unique() // => [1,2,3]

[{id:5, name:"Jay"}, {id:6, name:"Jay"}, {id: 5, name:"Jay"}].unique('id') 
  // => [{id:5, name:"Jay"}, {id:6, name:"Jay"}]

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

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
  )

很多人已经提到使用。。。

[...new Set(arr)];

这是一个很好的解决方案,但我的首选是与.filter一起使用的解决方案。在我看来,filter是获取唯一值的更自然的方法。您可以有效地删除重复项,而从数组中删除元素正是过滤器的作用所在。它还允许您链接.map、.reduce和其他.filter调用。我设计了这个解决方案。。。

const unique = () => {
  let cache;  
  return (elem, index, array) => {
    if (!cache) cache = new Set(array);
    return cache.delete(elem);
  };
};

myArray.filter(unique());

需要注意的是,你需要一个结束,但我认为这是一个值得的权衡。就性能而言,它比我看到的使用.filter的其他解决方案更具性能,但比[…new Set(arr)]性能更差。

另请参阅我的github包

您可以同时使用内置函数Array.prototype.filter()和Array.prototype.indexOf()

array.filter((x,y)=>array.indexOf(x)==y)

var arr=[1,2,3,3,4,5,5,6,7,8,9,6,9];var newarr=arr.filter((x,y)=>arr.indexOf(x)==y);console.log(newarr);