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

类似的问题:

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


当前回答

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

其他回答

看看这个。Jquery提供uniq方法:https://api.jquery.com/jQuery.unique/

var ids_array = []

$.each($(my_elements), function(index, el) {
    var id = $(this).attr("id")
    ids_array.push(id)
});

var clean_ids_array = jQuery.unique(ids_array)

$.each(clean_ids_array, function(index, id) {
   elment = $("#" + id)   // my uniq element
   // TODO WITH MY ELEMENT
});

这是因为0在JavaScript中是一个错误的值。

如果数组的值为0或任何其他错误值,则此[i]将是错误的。

在其他答案的基础上,这里有另一个变体,它使用可选标志来选择策略(保持第一次出现或保持最后一次出现):

不扩展Array.prototype

function unique(arr, keepLast) {
  return arr.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
unique(['a', 1, 2, '1', 1, 3, 2, 6]); // -> ['a', 1, 2, '1', 3, 6]
unique(['a', 1, 2, '1', 1, 3, 2, 6], true); // -> ['a', '1', 1, 3, 2, 6]

扩展Array.prototype

Array.prototype.unique = function (keepLast) {
  return this.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
['a', 1, 2, '1', 1, 3, 2, 6].unique(); // -> ['a', 1, 2, '1', 3, 6]
['a', 1, 2, '1', 1, 3, 2, 6].unique(true); // -> ['a', '1', 1, 3, 2, 6]

One Liner,纯JavaScript

使用ES6语法

list=list.filter((x,i,a)=>a.indexOf(x)==i)

x --> item in array
i --> index of item
a --> array reference, (in this case "list")

使用ES5语法

list = list.filter(function (x, i, a) { 
    return a.indexOf(x) == i; 
});

浏览器兼容性:IE9+

Array.prototype.getUnique = function() {
    var o = {}, a = []
    for (var i = 0; i < this.length; i++) o[this[i]] = 1
    for (var e in o) a.push(e)
    return a
}