Splice() 不会使数组为空
Splice() does not make the array empty
我有数组 x、y 和 z。
在遍历 x 时,根据条件我需要不断从 z 中删除元素。这是我正在尝试做的事情:
var x = ["test0", "test1", "test2"];
var y = ["test0", "test1", "test2"];
var z = ["test0", "test1", "test2"];
function myFunction(){
for (var i=0; i<x.length; i++){
for (var j=0; j<y.length; j++){
if(x[i] == y[j]){
z.splice(i,1);
}
}
}
document.getElementById("demo").innerHTML = z;
}
迭代结束时,z 应该为空。但它总是显示剩余 'test1' 个元素。
由于没有拼接正确的索引,我尝试执行 z.splice(i--,1)
但这也没有用。
请告知解决此问题的最佳方法是什么?
您可以通过跟踪从 z:
中删除的元素的数量来解决它
var numRemoved = 0;
for (var i=0; i<x.length; i++){
for (var j=0; j<y.length; j++){
if(x[i] == y[j]){
z.splice( i - numRemoved++ , 1 );
}
}
}
这很容易理解,如果你创建某种 table。问题是第一次拼接后,z的索引不像x和y的索引:
x[0] = j[0] : i = 0 -> z.splice(0, 1); - test0 is removed - z = ["test1", "test2"];
x[1] = j[1] : i = 1 -> z.splice(1, 1); - test2 is removed - z = ["test1"];
x[2] = j[2] : i = 2 -> z.splice(2, 1); - nothing is removed - z = ["test1"];
解决方案:
function myFunction() {
var removed = 0; // removed items counter
for (var i = 0; i < x.length; i++) {
for (var j = 0; j < y.length; j++) {
if (x[i] == y[j]) {
z.splice(i - removed, 1); // subtract removed counter from index
removed++; // increment removed counter
}
}
}
}
您可以使用 indexOf()
查找当前索引,而不是跟踪移动索引
for (var i=0; i<x.length; i++){
for (var j=0; j<y.length; j++){
if(x[i] == y[j]){
z.splice( z.indexOf(x[i]) , 1 );
}
}
}
正如答案所说,您的问题是拼接 z 意味着索引和值不再在数组之间对齐。从任何类型的列表中删除元素时,跟踪已删除索引的常见替代方法是从末尾迭代到开头,例如
var x = ["test0", "test1", "test2"];
var y = ["test0", "test1", "test2"];
var z = ["test0", "test1", "test2"];
function myFunction(){
for (var i=x.length; i>0; ){
for (var j=y.length; j> 0; ){
if(x[--i] == y[--j]){
z.splice(i,1);
}
}
}
document.write('"' + z.join() + '"');
}
myFunction();
并且如果你使用一些ES5引入的语法糖,reduceRight有助于减少代码量:
function myFunction(){
x.reduceRight(function(n, x, i) {
y.reduceRight(function(n, y) {
if (x == y) z.splice(i, 1)
}, null);
}, null)
document.write('"' + z.join() + '"');
}
我有数组 x、y 和 z。 在遍历 x 时,根据条件我需要不断从 z 中删除元素。这是我正在尝试做的事情:
var x = ["test0", "test1", "test2"];
var y = ["test0", "test1", "test2"];
var z = ["test0", "test1", "test2"];
function myFunction(){
for (var i=0; i<x.length; i++){
for (var j=0; j<y.length; j++){
if(x[i] == y[j]){
z.splice(i,1);
}
}
}
document.getElementById("demo").innerHTML = z;
}
迭代结束时,z 应该为空。但它总是显示剩余 'test1' 个元素。
由于没有拼接正确的索引,我尝试执行 z.splice(i--,1)
但这也没有用。
请告知解决此问题的最佳方法是什么?
您可以通过跟踪从 z:
中删除的元素的数量来解决它var numRemoved = 0;
for (var i=0; i<x.length; i++){
for (var j=0; j<y.length; j++){
if(x[i] == y[j]){
z.splice( i - numRemoved++ , 1 );
}
}
}
这很容易理解,如果你创建某种 table。问题是第一次拼接后,z的索引不像x和y的索引:
x[0] = j[0] : i = 0 -> z.splice(0, 1); - test0 is removed - z = ["test1", "test2"];
x[1] = j[1] : i = 1 -> z.splice(1, 1); - test2 is removed - z = ["test1"];
x[2] = j[2] : i = 2 -> z.splice(2, 1); - nothing is removed - z = ["test1"];
解决方案:
function myFunction() {
var removed = 0; // removed items counter
for (var i = 0; i < x.length; i++) {
for (var j = 0; j < y.length; j++) {
if (x[i] == y[j]) {
z.splice(i - removed, 1); // subtract removed counter from index
removed++; // increment removed counter
}
}
}
}
您可以使用 indexOf()
for (var i=0; i<x.length; i++){
for (var j=0; j<y.length; j++){
if(x[i] == y[j]){
z.splice( z.indexOf(x[i]) , 1 );
}
}
}
正如答案所说,您的问题是拼接 z 意味着索引和值不再在数组之间对齐。从任何类型的列表中删除元素时,跟踪已删除索引的常见替代方法是从末尾迭代到开头,例如
var x = ["test0", "test1", "test2"];
var y = ["test0", "test1", "test2"];
var z = ["test0", "test1", "test2"];
function myFunction(){
for (var i=x.length; i>0; ){
for (var j=y.length; j> 0; ){
if(x[--i] == y[--j]){
z.splice(i,1);
}
}
}
document.write('"' + z.join() + '"');
}
myFunction();
并且如果你使用一些ES5引入的语法糖,reduceRight有助于减少代码量:
function myFunction(){
x.reduceRight(function(n, x, i) {
y.reduceRight(function(n, y) {
if (x == y) z.splice(i, 1)
}, null);
}, null)
document.write('"' + z.join() + '"');
}