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];
}
}
但是当我推动更多的数字时,结果似乎不可预测
如何正确执行此操作?
说明一下:目的是剔除重复偶数次的数字。
您可以使用两个 reduce
和 Object.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);
大家好,例如我有一个数组:
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];
}
}
但是当我推动更多的数字时,结果似乎不可预测 如何正确执行此操作?
说明一下:目的是剔除重复偶数次的数字。
您可以使用两个 reduce
和 Object.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);