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

类似的问题:

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


当前回答

有时我需要从对象数组中获取唯一的引用。Lodash似乎是一个很好的助手,但我不认为过滤数组就可以为项目添加依赖项。

让我们假设在比较一个属性(例如id)时两个对象的姿势。

常量a=〔{id:3},{id:4}、{id:30}和{id:5}〕;

既然我们都喜欢一行代码片段,下面是如何做到这一点:

a.reduce((acc,curr)=>acc.find(e=>e.id==curr.id)?acc:[…acc,curr],[])

其他回答

我会对数组进行排序,然后所有重复项都是邻居。然后遍历数组一次并消除所有重复项。

function getUniques(array) {
  var l = array.length
  if(l > 1) {
    // get a cloned copy and sort it
    array = [...array].sort();
    var i = 1, j = 0;
    while(i < l) {
      if(array[i] != array[j]) {
        array[++j] = array[i];
      }
      i++;
    }
    array.length = j + 1;
  }
  return array;
}

我发现了一个使用jQuery的好方法

arr = $.grep(arr, function(v, k){
    return $.inArray(v ,arr) === k;
});

注:这段代码是从Paul Irish的打鸭子帖子中提取的-我忘记了给学分:P

这里有一个几乎是一行的O(n),保留了第一个元素,并且在这里你可以将你正在uniq'ing上的字段分开。

这是函数式编程中非常常见的技术——您可以使用reduce来构建返回的数组。因为我们这样构建数组,所以我们保证得到稳定的排序,这与[…new Set(array)]方法不同。我们仍然使用Set来确保没有重复,因此我们的累加器同时包含Set和我们正在构建的数组。

常量删除重复项=(arr)=>减少(([set,acc],item)=>集合有(item)?[set,acc]:[set.add(项目),(acc.push(项目)、acc)],[新设置(),[]])[1]

上述方法适用于简单值,但不适用于对象,类似于[…new Set(array)]的分解方式。如果项目是包含id属性的对象,您应该执行以下操作:

常量删除重复项=(arr)=>减少(([set,acc],item)=>集合有(item.id)?[set,acc]:[set.add(item.id),(acc.push(item),acc)],[新设置(),[]])[1]

一种可扩展、快速、高效且易于阅读的现代方法,使用iter ops库:

import {pipe, distinct} from 'iter-ops';

const input = [1, 1, 2, 2, 2, 3]; // our data

const i = pipe(input, distinct()); // distinct iterable

console.log([...i]); //=> [1, 2, 3]

如果您的输入是一个对象数组,则只需为不同的运算符提供一个键选择器。

在我的解决方案中,我在过滤之前对数据进行排序:

const uniqSortedArray = dataArray.sort().filter((v, idx, t) => idx==0 || v != t[idx-1]);