从Javascript Array中删除重复项时出错

时间:2016-05-25 15:04:19

标签: javascript arrays

更新

这是问题的一个小问题:https://jsfiddle.net/q9c5fku3/当我运行该代码并查看控制台时,我看到它的控制台。在数组中记录一个不同的数字。

感谢您的回复,对不起,我得到了投票,但这真让我感到困惑。

我已经使用不同的数字再次尝试过,我想知道你们可以测试这些数字,看看你是否得到了不同的结果?

    var myArray = [621608617992776, 621608617992776, 10156938936550295, 621608617992776, 10156938936550295, 10156938936550295, 621608617992776, 10156938936550295];
    console.log(myArray);

    var myArrayTrimmed = [];

    for(var i in myArray){
        if(myArrayTrimmed.indexOf(myArray[i]) === -1){
            myArrayTrimmed.push(myArray[i]);
        }
    }
    console.log(myArrayTrimmed);

这在控制台中给了我以下数组:

[621608617992776, 10156938936550296]

由于某种原因,第二个数字增加了1.

====================

原始问题:

我有这个数组:

var myArray = [100, 200, 100, 200, 100, 100, 200, 200, 200, 200];

我试图创建一个名为myArrayTrimmed的新数组,它与上面的数组相同,只不过它会删除重复数据。这应该导致:

var myArrayTrimmed = [100, 200];

这是我尝试实现此目的的代码:

var myArray = [100, 200, 100, 200, 100, 100, 200, 200, 200, 200];
var myArrayTrimmed = [];

for(var i in myArray){
    if(myArrayTrimmed.indexOf(myArray[i]) === -1){
        myArrayTrimmed.push(myArray[i]);
    }
}
console.log(myArrayTrimmed);

这不能正常工作,虽然它正在删除重复项,但由于某种原因,它会从200减去数字1,因此控制台中的输出为:

[100, 199]

我认为这必须归功于代码中的-1,但我不知道如何删除重复内容。

3 个答案:

答案 0 :(得分:2)

我相信这是最好的方法

var myArray = [100, 200, 100, 200, 100, 100, 200, 200, 200, 200],
    reduced = Object.keys(myArray.reduce((p,c) => (p[c] = true,p),{}));
console.log(reduced);

好吧..即使这个是O(n)而其他人都是O(n ^ 2)我很想看到这个缩小/查找表和filter / indexOf组合之间的基准比较(我选择Jeetendras非常好实施https://stackoverflow.com/a/37441144/4543207)。我准备一个100K项目数组,填充0-9999范围内的随机正整数,并删除重复项。我重复测试了10次,结果的平均值表明它们的性能不匹配。

  • 在firefox v47中减少& lut:14.85ms vs filter& indexOf:2836ms
  • 在chrome v51中减少& lut:23.90ms vs filter& indexOf:1066ms

好到目前为止一切都那么好。但是这次以ES6风格正确地做到了。它看起来很酷..!但截至目前,它对抗强大的解决方案将如何表现对我来说是一个谜。让我们先看看代码然后对它进行基准测试。

var myArray = [100, 200, 100, 200, 100, 100, 200, 200, 200, 200],
    reduced = [...myArray.reduce((p,c) => p.set(c,true),new Map()).keys()];
console.log(reduced);

哇,这很短......!但是性能怎么样?这很漂亮......由于过滤器/ indexOf的重量超过了我们的肩膀,我现在可以在0..99999范围内测试一组1M的正整数随机项,以获得10次连续测试的平均值。我可以说这次是一场真正的比赛。自己看结果:)

var ranar = [],
     red1 = a => Object.keys(a.reduce((p,c) => (p[c] = true,p),{})),
     red2 = a => reduced = [...a.reduce((p,c) => p.set(c,true),new Map()).keys()],
     avg1 = [],
     avg2 = [],
       ts = 0,
       te = 0,
     res1 = [],
     res2 = [],
     count= 10;
for (var i = 0; i<count; i++){
  ranar = (new Array(1000000).fill(true)).map(e => Math.floor(Math.random()*100000));
  ts = performance.now();
  res1 = red1(ranar);
  te = performance.now();
  avg1.push(te-ts);
  ts = performance.now();
  res2 = red2(ranar);
  te = performance.now();
  avg2.push(te-ts);
}

avg1 = avg1.reduce((p,c) => p+c)/count;
avg2 = avg2.reduce((p,c) => p+c)/count;

console.log("reduce & lut took: " + avg1 + "msec");
console.log("map & spread took: " + avg2 + "msec");

你会使用哪一个..?好吧不是那么快......!不要被欺骗。地图处于位移状态。现在看......在上述所有情况下,我们填充一个大小为n的数组,其数量为&lt; ñ。我的意思是我们有一个100的数组,我们填充随机数0..9所以有确定的重复和“几乎”肯定每个数字都有重复。如果我们用随机数0..9999填充大小为100的数组怎么样。我们现在看看家里的地图播放。这次是100K项目的数组,但是随机数范围是0..100M。我们将进行100次连续测试以平均结果。好的,让我们看看赌注..! &lt; - 没有拼写错误

var ranar = [],
     red1 = a => Object.keys(a.reduce((p,c) => (p[c] = true,p),{})),
     red2 = a => reduced = [...a.reduce((p,c) => p.set(c,true),new Map()).keys()],
     avg1 = [],
     avg2 = [],
       ts = 0,
       te = 0,
     res1 = [],
     res2 = [],
     count= 100;
for (var i = 0; i<count; i++){
  ranar = (new Array(100000).fill(true)).map(e => Math.floor(Math.random()*100000000));
  ts = performance.now();
  res1 = red1(ranar);
  te = performance.now();
  avg1.push(te-ts);
  ts = performance.now();
  res2 = red2(ranar);
  te = performance.now();
  avg2.push(te-ts);
}

avg1 = avg1.reduce((p,c) => p+c)/count;
avg2 = avg2.reduce((p,c) => p+c)/count;

console.log("reduce & lut took: " + avg1 + "msec");
console.log("map & spread took: " + avg2 + "msec");

现在这是Map()的壮观复出..!可能现在你可以在想要删除欺骗时做出更好的决定。

好吧,我们现在都很高兴。但是主角一直伴随着掌声。我相信你们有些人想知道Set对象会做什么。既然我们对ES6持开放态度并且我们知道Map是之前游戏的赢家,那么让我们将Map与Set进行比较。这次典型的皇马对阵巴塞罗那比赛......或者是这样?让我们看看谁将赢得el classico:)

var ranar = [],
     red1 = a => reduced = [...a.reduce((p,c) => p.set(c,true),new Map()).keys()],
     red2 = a => Array.from(new Set(a)),
     avg1 = [],
     avg2 = [],
       ts = 0,
       te = 0,
     res1 = [],
     res2 = [],
     count= 100;
for (var i = 0; i<count; i++){
  ranar = (new Array(100000).fill(true)).map(e => Math.floor(Math.random()*10000000));
  ts = performance.now();
  res1 = red1(ranar);
  te = performance.now();
  avg1.push(te-ts);
  ts = performance.now();
  res2 = red2(ranar);
  te = performance.now();
  avg2.push(te-ts);
}

avg1 = avg1.reduce((p,c) => p+c)/count;
avg2 = avg2.reduce((p,c) => p+c)/count;

console.log("map & spread took: " + avg1 + "msec");
console.log("set & A.from took: " + avg2 + "msec");

哇..男人..!出乎意料的是,它根本没有成为一个经典的。更像是巴塞罗那足球俱乐部对阵CA Osasuna:))

答案 1 :(得分:0)

您可以使用以下代码有效删除重复元素 -

var myArrayTrimmed = myArray.filter(function(elem, pos) {
return myArray.indexOf(elem) == pos;
});

myArrayTrimmed将包含唯一值。

答案 2 :(得分:0)

希望这会有用

var myArray = [100, 200, 100, 200, 100, 100, 200, 200, 200, 200];
var myArrayTrimmed = [];
myArray.forEach(function(item){
 if(myArrayTrimmed.indexOf(item) ==-1){
   myArrayTrimmed.push(item);
}

})
console.log(myArrayTrimmed);

选中此jsfiddle