我有一组数字,我需要确保它们是唯一的。我在互联网上找到了下面的代码片段,它工作得很好,直到数组中有一个零。我在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数组中删除重复值
类似的问题:
获取数组中的所有非唯一值(即:重复/多次出现)
我查看了Joeytje50在jsperf上的代码,他比较了许多替代方案。他的代码有很多小错误,这对性能和正确性产生了影响。
更重要的是,他正在一个非常小的阵列上进行测试。我用1000个整数组成了一个数组。每个整数是0到1000之间的随机整数的100倍。这使得平均约1000/e=368个重复。结果在jsperf。
这是一个可能需要效率的更现实的场景。这些变化使声明发生了戏剧性的变化(特别是被吹捧为最快的代码远没有快到哪里去)。明显的赢家是使用哈希技术的地方,最好的是
Array.prototype.getUnique3 = function(){
var u = Object.create(null), a = [];
for(var i = 0, l = this.length; i < l; ++i){
if(this[i] in u) continue;
a.push(this[i]);
u[this[i]] = 1;
}
return a.length;
}
要删除重复项,可能有两种情况。首先,所有数据都不是对象,其次所有数据都是对象。
如果所有数据都是任何类型的原始数据类型,如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数组上。
看来我们已经失去了拉斐尔的答案,这是几年来公认的答案。如果没有混合类型数组,这是(至少在2017年)性能最好的解决方案:
Array.prototype.getUnique = function(){
var u = {}, a = [];
for (var i = 0, l = this.length; i < l; ++i) {
if (u.hasOwnProperty(this[i])) {
continue;
}
a.push(this[i]);
u[this[i]] = 1;
}
return a;
}
如果您有混合类型数组,则可以序列化哈希键:
Array.prototype.getUnique = function() {
var hash = {}, result = [], key;
for ( var i = 0, l = this.length; i < l; ++i ) {
key = JSON.stringify(this[i]);
if ( !hash.hasOwnProperty(key) ) {
hash[key] = true;
result.push(this[i]);
}
}
return result;
}
一个简单的代码如下:
let arr = [1,'k',12,1,1,'k','12'];
let distictArr=arr.filter((item, index, arr) => arr.indexOf(item) === index);
console.log(distictArr); // [1, 'k', 12, '12']