Javascript spliced ​​in jQuery.each ()?

var results = ['one', 'two', 'one hundred', 'three']; var removal = []; $.each(results, function(i) { removal.push(i); if (results[i].indexOf('one') == -1){ console.log('Removing:' + results[i] + '(' + removal[i] + ')'); results = results.splice(removal[i], 1); } }); 

I have the following code, but it breaks after it removes the first result.

I want him to delete everything that does not contain the word "one."

I assume that it breaks because the deletion order changes after deletion.

What am I doing wrong?

+6
source share
4 answers

You should not splice the array while you repeat it with $.each() .

Since you are changing the length of the array, you go beyond the ending index since.

Just use the for loop and adjust i when deleting the element ...

 var results = ['one', 'two', 'one hundred', 'three']; var removal = []; for(var i = 0; i < results.length; i++) { removal.push(i); if (results[i].indexOf('one') == -1){ console.log('Removing:' + results[i] + '(' + removal[i] + ')'); results.splice(i, 1); i--; } }; 

Please note that I changed this ...

 results = results.splice(removal[i], 1); 

to that...

 results.splice(removal[i], 1); 

You do not want to, since splice() modifies the original and returns deleted items.

+17
source
 var myArr = [0,1,2,3,4,5,6]; 

Problem:

 myArr.splice(2,1); \\ [0, 1, 3, 4, 5, 6]; 

now 3 movements in the second position, and the length decreases by 1, which creates a problem.

Solution: A simple solution will iterate backwards when spliced.

 var i = myArr.length; while (i--) { console.log(myArr); myArr.splice(i,1); } 

Conclusion:

 [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4] [0, 1, 2, 3] [0, 1, 2] [0, 1] [0] 
+3
source

The problem is that the $.each() function $.each() through the array in order from the first element and internally sets the range of indices to be used at the beginning. Therefore, when you remove elements from this array, it does not know that you did it.

You can easily get around this with the standard for statement. If you loop back from the end of the list to the beginning, you can delete items without affecting the loop. If you are looping ahead, you need to set up a loop counter every time you remove an element from the array.

+1
source

Yes, changing the structure of the array when you loop, will greatly damage the chaos. Try using a temporary airfield:

 var results = ['one', 'two', 'one hundred', 'three']; var removal = []; var newResults = []; $.each(results, function(i) { removal.push(i); if (results[i].indexOf('one') > -1){ newResults.push(i); } else { console.log('Removing:' + results[i] + '(' + removal[i] + ')'); } }); results = newResults; 
-1
source

Source: https://habr.com/ru/post/907447/


All Articles