在開發JavaScript應用的過程中,經常會遇到在循環中移除指定元素的需求。
按照常規的思路,就是對數組進行一個for循環,然后在循環里面進行if判斷,在判斷中刪除掉指定元素即可。
但是實際情況往往不會像預想的那樣順利運行。
出現的問題場景還原
(function () { var arr = [1, 2, 2, 3, 4, 5]; for (var i = 0; i < arr.length; i++){ // 打印數組中的情況,便於跟蹤數組中數據的變化 console.log(i + ' = ' + arr[i]); // 刪除掉所有為2的元素 if(arr[i] === 2) { arr.splice(i, 1); } } console.log(arr); })();
從最終的結果可以看到,這段代碼實際上只刪除掉了匹配的其中一個元素,而另一個匹配條件的元素還存在,並不符合程序設計的初衷。
而從打印出來的運行過程不難發現,產生這個結果的原因是因為,當刪除掉了一個元素后,數組中元素的索引(下標)發生了實時變化,造成了程序的異常。
解決問題的方法
找到了出現問題的原因,就不難解決問題了。
方法1:實時調整數組中元素的下標對應關系。
(function () { var arr = [1, 2, 2, 3, 4, 5]; for (var i = 0; i < arr.length; i++){ // 打印數組中的情況,便於跟蹤數組中數據的變化 console.log(i + ' = ' + arr[i]); // 刪除掉所有為2的元素 if(arr[i] === 2) { arr.splice(i--, 1); } } console.log(arr); })();
出現問題的原因,是因為移除掉中間的一個元素之后,該元素后面的元素的索引(下標)都往前加1了,那么我們可以在刪除元素后手動將循環中的下標重置為現在對應的下標即可(i--)。
方法2:從后往前遍歷數組元素。
(function () { var arr = [1, 2, 2, 3, 4, 5]; for (var i = arr.length - 1; i >= 0; i--) { // 打印數組中的情況,便於跟蹤數組中數據的變化 console.log(i + ' = ' + arr[i]); // 刪除掉所有為2的元素 if(arr[i] === 2) { arr.splice(i, 1); } } console.log(arr); })();
出現問題的原因,是因為移除掉中間的一個元素之后,該元素后面的元素的索引(下標)都往前加1了,那么只要是從后往前循環,就可以不用管后面元素的索引(下標)了。
方法3:使用while循環代替for循環(還是從后往前循環)。
(function () { var arr = [1, 2, 2, 3, 4, 5]; var i = arr.length; while(i--) { console.log(i + ' = ' + arr[i]); if(arr[i] === 2) { arr.splice(i, 1); } } console.log(arr); })();
同上面從后往前循環的原理一致,只是將for循環使用了while循環代替。