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

类似的问题:

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


当前回答

已经有很多好答案了。这是我的方法。

var removeDuplicates = function(nums) {
    let filteredArr = [];
    nums.forEach((item) => {
        if(!filteredArr.includes(item)) {
            filteredArr.push(item);
        }
    })

  return filteredArr;
}

其他回答

这已经得到了很多回答,但并没有解决我的特殊需求。

许多答案是这样的:

a.filter((item, pos, self) => self.indexOf(item) === pos);

但这对复杂对象的数组不起作用。

假设我们有一个这样的数组:

const a = [
 { age: 4, name: 'fluffy' },
 { age: 5, name: 'spot' },
 { age: 2, name: 'fluffy' },
 { age: 3, name: 'toby' },
];

如果我们想要具有唯一名称的对象,我们应该使用array.prototype.findIndex而不是array.protoype.indexOf:

a.filter((item, pos, self) => self.findIndex(v => v.name === item.name) === pos);

如果您有一个对象数组,并且需要uniqueBy函数,例如通过id字段:

function uniqueBy(field, arr) {
   return arr.reduce((acc, curr) => {
     const exists = acc.find(v => v[field] === curr[field]);
     return exists ? acc : acc.concat(curr);
   }, [])
}

如果顺序不重要,那么我们可以创建一个哈希,并获取密钥以创建唯一的数组。

var ar = [1,3,4,5,5,6,5,6,2,1];
var uarEle = {};
links.forEach(function(a){ uarEle[a] = 1; });
var uar = keys(uarEle)

uar将具有唯一的数组元素。

您可以使用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>

我将所有答案分成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测试了最后一段代码,它看起来比对象方法更快。