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

类似的问题:

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


当前回答

下面是另一种使用比较器的方法(我更关心干净的代码而不是性能):

const list = [
    {name: "Meier"},
    {name: "Hans"},
    {name: "Meier"},
]
const compare = (a, b) => a.name.localeCompare(b.name);
const uniqueNames = list.makeUnique(compare);
uniqueNames.pushIfAbsent({name: "Hans"}, compare);

原型声明:

declare global {
    interface Array<T>  {
        pushIfAbsent(item: T, compare:(a:T, b:T)=>number): number;
    }
    interface Array<T>  {
        makeUnique(compare:(a:T, b:T)=>number): Array<T>;
    }
}
Array.prototype.pushIfAbsent = function <T>(this:T[], item:T, compare:(a:T, b:T)=>number) {
    if (!this.find(existing => compare(existing, item)===0)) {
        return this.push(item)
    } else {
        return this.length;
    }
}
Array.prototype.makeUnique = function <T>(this:T[], compare:(a:T, b:T)=>number) {
    return this.filter((existing, index, self) => self.findIndex(item => compare(existing, item) == 0) == index);
}

其他回答

魔术

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

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

许多答案是这样的:

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

使用ES6新设置

变量数组=[3,7,5,3,2,5,2,7];var unique_array=[…新集合(数组)];console.log(unique_array);//输出=[3,7,5,2]

使用For循环

变量数组=[3,7,5,3,2,5,2,7];for(var i=0;i<array.length;i++){for(变量j=i+1;j<array.length;j++){如果(array[i]===array[j]){阵列.拼接(j,1);}}}console.log(数组);//输出=[3,7,5,2]

如前所述,[…new Set(value)]是最好的选项,如果您可以使用的话。

否则,这里有一个单行程序,它不会为每个索引迭代数组:

values.sort().filter((val, index, arr) => index === 0 ? true : val !== arr[index - 1]);

这只是将每个值与前面的值进行比较。结果将被排序。

例子:设值=[1,2,3,3,4,5,5,4,4,3,1,1,3,3];let unique=values.sort().filter((val,index,arr)=>索引==0?真:val!==arr[索引-1]);console.log(唯一);

这是一个ES6函数,它从对象数组中删除重复项,并按指定的对象属性进行筛选

function dedupe(arr = [], fnCheck = _ => _) {
  const set = new Set();
  let len = arr.length;

  for (let i = 0; i < len; i++) {
    const primitive = fnCheck(arr[i]);
    if (set.has(primitive)) {
      // duplicate, cut it
      arr.splice(i, 1);
      i--;
      len--;
    } else {
      // new item, add it
      set.add(primitive);
    }
  }

  return arr;
}

const test = [
    {video:{slug: "a"}},
    {video:{slug: "a"}},
    {video:{slug: "b"}},
    {video:{slug: "c"}},
    {video:{slug: "c"}}
]
console.log(dedupe(test, x => x.video.slug));

// [{video:{slug: "a"}}, {video:{slug: "b"}}, {video:{slug: "c"}}]