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

类似的问题:

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


当前回答

ES6/ES2015更新答案:使用Set和排列运算符(感谢le-m),单线解决方案为:

let uniqueItems = [...new Set(items)]

哪个会返回

[4, 5, 6, 3, 2, 23, 1]

其他回答

还有另一个答案,只是因为我为我的特定用例写了一个答案。我碰巧正在对阵列进行排序,如果我正在排序,我可以使用它来消除重复数据。

注意,我的排序处理我的特定数据类型,您可能需要不同的排序,这取决于您拥有的元素类型。

var sortAndDedup = function(array) {
  array.sort(function(a,b){
    if(isNaN(a) && isNaN(b)) { return a > b ? 1 : (a < b ? -1 : 0); }
    if(isNaN(a)) { return 1; }
    if(isNaN(b)) { return -1; }
    return a-b;
  });

  var newArray = [];
  var len = array.length;
  for(var i=0; i<len; i++){
    if(i === 0 || array[i] != array[i-1]){
      newArray.push(array[i]);
    }
  }
};

魔术

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)))

var myArray=[“a”,2,“a”、2,“b”,“1”];常量=[];myArray.forEach((t)=>!uniques.includes(t)和uniques.push(t));console.log(uniques);

我将所有答案分成4种可能的解决方案:

使用对象{}防止重复使用助手数组[]使用筛选器+indexOf奖金ES6设置方法。

以下是答案中的示例代码:

使用对象{}防止重复

function uniqueArray1( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });

  return Object.keys(j).map(function(v){
    return j[v];
  });
} 

使用助手数组[]

function uniqueArray2(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.push(arr[i]);
    return a;
}

使用筛选器+indexOf

function uniqueArray3(a) {
  function onlyUnique(value, index, self) { 
      return self.indexOf(value) === index;
  }

  // usage
  var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

  return unique;
}

使用ES6[…新集合(a)]

function uniqueArray4(a) {
  return [...new Set(a)];
}

我想知道哪一个更快。我已经制作了测试功能的GoogleSheet样本。注意:ECMA 6在Google Sheets中不可用,所以我无法测试它。

以下是测试结果:

我希望看到使用对象{}的代码将获胜,因为它使用哈希。因此,我很高兴测试在Chrome和IE中显示了该算法的最佳结果。感谢@rab的代码。

2020年更新

启用谷歌脚本的ES6引擎。现在我用Sets测试了最后一段代码,它看起来比对象方法更快。

如果您对额外的依赖关系感到满意,或者您的代码库中已经有一个库,那么可以使用LoDash(或Undercore)从阵列中删除重复项。

用法

如果您的代码库中还没有它,请使用npm安装它:

npm install lodash

然后按如下方式使用:

import _ from 'lodash';
let idArray = _.uniq ([
    1,
    2,
    3,
    3,
    3
]);
console.dir(idArray);

输出:

[ 1, 2, 3 ]