JavaScript 数组:只保留出现奇数次的值,包括一次

JavaScript Arrays : Keep only values that are present an odd number of times, including once

大家好,例如我有一个数组:

myArray[5,4,1,2,1,4,5,6,7,8,9,10,1,2,1,5,3,2]

我正在对数组进行排序:

[1, 1, 1, 1, 10, 2, 2, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 9]

我只想删除两个重复项,所以我想要的数组将是

[10,2,3,5,6,7,8,9]

所以我正在使用拼接:

for (var index = 0; index < myArray.length +1; ++myArray) {
  if(myArray[index+1]== myArray[index]) {
    myArray.splice(index);
    myArray.splice[index+1];
  }
}

但是当我推动更多的数字时,结果似乎不可预测 如何正确执行此操作?

说明一下:目的是剔除重复偶数次的数字。

您可以使用两个 reduceObject.keys() 来完成此操作。首先将值添加到对象,然后使用 % 2 检查每个值并添加到数组。

var myArray = [5,4,1,2,1,4,5,6,7,8,9,10,1,2,1,5,3,2];
var obj = myArray.reduce(function(o, e) {
  o[e] = (o[e] || 0)+1;
  return o;
}, {})

var result = Object.keys(obj).reduce(function(r, e) {
  if(obj[e] % 2) r.push(Number(e));
  return r;
}, []);

console.log(result)

这是一个 ECMAScript2015 解决方案:

var myArray = [5,4,1,2,1,4,5,6,7,8,9,10,1,2,1,5,3,2];
var count = myArray.reduce((count, num) => 
                           (count[num] = (count[num] || 0) + 1, count), {});
myArray = Object.keys(count).filter(num => count[num] % 2).map(Number);
console.log(myArray);

计数变量是一个object,其属性是原始数组中的数字。每个属性的值都是该数字在原始数组中出现的次数。

然后迭代键以仅将那些具有奇数值(即出现次数)的键放入最终数组。由于 object 属性按数字顺序迭代(当为数字时),结果会自动按数字排序。

关于您的代码:

您的 for 循环有一些问题:

for (var index = 0; index < myArray.length +1; ++myArray) {
  if(myArray[index+1]== myArray[index]) {
    myArray.splice(index);
    myArray.splice[index+1];
  }
}
  • 您当然不想增加 myArray,但是 index
  • 边界条件不应该是 length+1,而是 length-1,因为在 body 中你有 myArray[index+1] 并且不想越界。
  • 但更重要的是,在 for 循环中执行 splice 会使元素移动位置,然后当您仍然递增 index 时,您将跳过元素。

简而言之,你不应该在这样的循环中使用splice。您可以通过相反的方向解决这个问题,并从数组的末尾开始工作。

但是上面建议的代码没有这个问题,也省去了排序的步骤。

这里还有一个方法,通过排序后的lastIndexOf键减去indexOf键来检查是否为奇数个元素:

var myArray = [5,4,1,2,1,4,5,6,7,8,9,10,1,2,1,5,3,2];

var result = myArray.sort().filter(function(key, idx) {
  return myArray.indexOf(key) === idx && //handle first instance only
         (myArray.lastIndexOf(key) - myArray.indexOf(key)) % 2 === 0;
});

console.log(result);