看起来你正在尝试这样做?
使用 Array.prototype.splice 迭代和变异数组
var pre = document.getElementById('out');
function log(result) {
pre.appendChild(document.createTextNode(result + '\n'));
}
var review = ['a', 'b', 'c', 'b', 'a'];
review.forEach(function(item, index, object) {
if (item === 'a') {
object.splice(index, 1);
}
});
log(review);
<pre id="out"></pre>
这适用于没有2个与相邻数组项相同的值的简单情况,其他明智的做法是你有这个问题。
var pre = document.getElementById('out');
function log(result) {
pre.appendChild(document.createTextNode(result + '\n'));
}
var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];
review.forEach(function(item, index, object) {
if (item === 'a') {
object.splice(index, 1);
}
});
log(review);
<pre id="out"></pre>
那么,在迭代和改变数组时,我们能做些什么来解决这个问题呢?好吧,通常的解决方案是反向工作。使用ES3,但如果你愿意,你可以用糖
var pre = document.getElementById('out');
function log(result) {
pre.appendChild(document.createTextNode(result + '\n'));
}
var review = ['a' ,'a', 'b', 'c', 'b', 'a', 'a'],
index = review.length - 1;
while (index >= 0) {
if (review[index] === 'a') {
review.splice(index, 1);
}
index -= 1;
}
log(review);
<pre id="out"></pre>
好的,但你想使用ES5迭代方法。好吧,选项是使用Array.prototype.filter,但这不会改变原始数组,而是创建一个新数组,所以虽然你可以得到正确的答案,但它不是你似乎指定的东西。
我们也可以使用ES5 Array.prototype.reduceRight,而不是通过它的迭代属性来简化其简化属性,即反向迭代。
var pre = document.getElementById('out');
function log(result) {
pre.appendChild(document.createTextNode(result + '\n'));
}
var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];
review.reduceRight(function(acc, item, index, object) {
if (item === 'a') {
object.splice(index, 1);
}
}, []);
log(review);
<pre id="out"></pre>
或者我们可以像这样使用ES5 Array.protoype.indexOf。
var pre = document.getElementById('out');
function log(result) {
pre.appendChild(document.createTextNode(result + '\n'));
}
var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'],
index = review.indexOf('a');
while (index !== -1) {
review.splice(index, 1);
index = review.indexOf('a');
}
log(review);
<pre id="out"></pre>
但是你特别想使用ES5 Array.prototype.forEach,那么我们能做些什么呢?好吧,我们需要使用Array.prototype.slice来制作数组的浅层副本,并使用Array.prototype.reverse,这样我们就可以反向工作来改变原始数组。
var pre = document.getElementById('out');
function log(result) {
pre.appendChild(document.createTextNode(result + '\n'));
}
var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];
review.slice().reverse().forEach(function(item, index, object) {
if (item === 'a') {
review.splice(object.length - 1 - index, 1);
}
});
log(review);
<pre id="out"></pre>
最后,ES6为我们提供了一些进一步的替代方案,我们不需要制作浅层副本并反转它们。值得注意的是,我们可以使用生成器和迭代器。然而,目前的支持率相当低。
var pre = document.getElementById('out');
function log(result) {
pre.appendChild(document.createTextNode(result + '\n'));
}
function* reverseKeys(arr) {
var key = arr.length - 1;
while (key >= 0) {
yield key;
key -= 1;
}
}
var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];
for (var index of reverseKeys(review)) {
if (review[index] === 'a') {
review.splice(index, 1);
}
}
log(review);
<pre id="out"></pre>
在上述所有内容中需要注意的是,如果您要从数组中剥离NaN,那么与equals进行比较将不起作用,因为在Javascript中是错误的。但是,我们将在解决方案中忽略这一点,因为它是另一个未指定的边缘情况。NaN === NaN
因此,我们有了它,一个更完整的答案,其中包含仍然具有边缘情况的解决方案。第一个代码示例仍然是正确的,但如前所述,它并非没有问题。