通常我們需要刪除數據中特定元素,這個我個人比較喜歡用Array.splice(beginIndex,deleteCount,[,itemToAdd,..])。這個方法的第一個參數是在哪個下標元素開始操作。第二個參數是需要刪除的元素的個數。后面的參數任意個,是需要在beginIndex出添加的元素。
如果要批量刪除數組元素的話,可得注意一個地方了。先看看下面的例子:
var arr =["a","b","c","d","e","f"];
//本來想刪除 e f
arr.splice(4,1);
arr.splice(5,1);//這時候數組長度是5。想刪除第六個元素當然是不可能的
alert(arr);//a,b,c,d,e f 沒有刪掉
也就是在批量刪除的時候,其實數組長度也在發生變化。幾番調試糾結之后,發現如果從一個數組元素的后面刪除到前面,這樣不管長度怎么變化都沒有關系了 。
var arr =["a","b","c","d","e","f"];
var toDeleteIndexes= [5,3,1];
for (var i=0;i<toDeleteIndexes.length ; i++){
arr.splice(toDeleteIndexes[i],1);
}
alert(arr);//a,c,e works
事實上上面的toDeleteIndexes并不是規規矩矩的排序的,于是首先想到是不是可以先將toDeleteIndexes排序了?下面是方法一
function removeBatch2(arr,toDeleteIndexes){
toDeleteIndexes.sort();//按大到小排列
for (var i=toDeleteIndexes.length-1 ;i>=0; i--){
arr.splice(toDeleteIndexes[i],1);
}
return arr;
}
var arr =["a","b","c","d","e","f"];
var toDeleteIndexes= [5,1,3];
//刪除a數組中下表為5,1,3的數組
alert(removeBatch2(arr,toDeleteIndexes));
上面的函數能批量刪除元素,下面這種方法(方法二)也可行:
//批量刪除指定下標的數據元素
function removeBatch(arr,toDeleteIndexes){
var result=[];
for (var i=0;i<arr.length ; i++){
var o = arr[i];
var needDelete = false;
for (var j=0;j<toDeleteIndexes.length ; j++){
if(i==toDeleteIndexes[j]){needDelete=true; break;}
}
if(!needDelete){
result.push(arr[i]);
}
}
return result;
}
var arr =["a","b","c","d","e","f"];
var toDeleteIndexes= [5,1,3];
//刪除a數組中下表為5,1,3的數組
alert(removeBatch(arr,toDeleteIndexes));
這種方法是一種典型的用空間復雜度換取時間復雜度。這兩種方法究竟孰優孰劣,可以簡單的計算一下循環次數。(n代表arr長度,m代表toDeleteIndexes長度)
方法一的運算次數:通常sort最多是n*(n-1)/2 次。后面循環了m*( n*(n-1)/2)。splice應該也循環了begin次數。所以總的運算次數應該是(m+1)*n*(n-1)/2次
方法二的運算次數:n*m/2 for (var j=0;j<toDeleteIndexes.length ; j++){if(i==toDeleteIndexes[j]){needDelete=true; break;} 算m/2次。
方法二需要重新申明一個數組,占內存應該會大些。
關于算法方面的結論,都是估算,還請讀者指點。
總的來說,對于有確定的排序下標的批量刪除,速度是最快的,不需要對下標排序。大家有更好的方法,歡迎交流。