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

类似的问题:

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


当前回答

对于一个元组数组,我将把它们放到一个Map中,让它完成工作。使用此方法时,您必须注意要使用的密钥:

const arrayOfArraysWithDuplicates = [
    [1, 'AB'],
    [2, 'CD'],
    [3, 'EF'],
    [1, 'AB'],
    [2, 'CD'],
    [3, 'EF'],
    [3, 'GH'],
]

const uniqueByFirstValue = new Map();
const uniqueBySecondValue = new Map();

arrayOfArraysWithDuplicates.forEach((item) => {
    uniqueByFirstValue.set(item[0], item[1]);
    uniqueBySecondValue.set(item[1], item[0]);
});

let uniqueList = Array.from( uniqueByFirstValue, ( [ value, name ] ) => ( [value, name] ) );

console.log('Unique by first value:');
console.log(uniqueList);

uniqueList = Array.from( uniqueBySecondValue, ( [ value, name ] ) => ( [value, name] ) );

console.log('Unique by second value:');
console.log(uniqueList);

输出:

Unique by first value:
[ [ 1, 'AB' ], [ 2, 'CD' ], [ 3, 'GH' ] ]

Unique by second value:
[ [ 'AB', 1 ], [ 'CD', 2 ], [ 'EF', 3 ], [ 'GH', 3 ] ]

其他回答

魔术

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

您也可以使用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"}]

最简单、最快(在Chrome中)的方法:

Array.prototype.unique = function() {
    var a = [];
    for (var i=0, l=this.length; i<l; i++)
        if (a.indexOf(this[i]) === -1)
            a.push(this[i]);
    return a;
}

只需遍历数组中的每个项,测试该项是否已经在列表中,如果没有,则推送到返回的数组。

根据JSBench的说法,这个函数是我在任何地方都能找到的最快的函数——尽管可以随意添加自己的函数。

非原型版本:

function uniques(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;
}

排序

当还需要对阵列进行排序时,以下是最快的:

Array.prototype.sortUnique = function() {
    this.sort();
    var last_i;
    for (var i=0;i<this.length;i++)
        if ((last_i = this.lastIndexOf(this[i])) !== i)
            this.splice(i+1, last_i-i);
    return this;
}

或非原型:

function sortUnique(arr) {
    arr.sort();
    var last_i;
    for (var i=0;i<arr.length;i++)
        if ((last_i = arr.lastIndexOf(arr[i])) !== i)
            arr.splice(i+1, last_i-i);
    return arr;
}

在大多数非Chrome浏览器中,这也比上述方法更快。

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

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

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

要删除重复项,可能有两种情况。首先,所有数据都不是对象,其次所有数据都是对象。

如果所有数据都是任何类型的原始数据类型,如int、float、string等,那么您可以遵循以下一种

const uniqueArray = [...new Set(oldArray)]

但假设您的数组包含以下JS对象

{
    id: 1,
    name: 'rony',
    email: 'rony@example.com'
}

然后,要获取所有唯一的对象,可以执行以下操作

let uniqueIds = [];
const uniqueUsers = oldArray.filter(item => {
    if(uniqueIds.includes(item.id)){
        return false;
    }else{
        uniqueIds.push(item.id);
        return true;
    }
})

您也可以使用此方法使任何类型的数组成为唯一的。只需将跟踪键保留在uniqueIds数组上。