怎樣高效的批量刪除javascript 數(shù)組中的元素?
通常我們需要刪除數(shù)據(jù)中特定元素,這個我個人比較喜歡用Array.splice(beginIndex,deleteCount,[,itemToAdd,..])。這個方法的第一個參數(shù)是在哪個下標(biāo)元素開始操作。第二個參數(shù)是需要刪除的元素的個數(shù)。后面的參數(shù)任意個,是需要在beginIndex出添加的元素。
如果要批量刪除數(shù)組元素的話,可得注意一個地方了。先看看下面的例子:
var arr =["a","b","c","d","e","f"];
//本來想刪除 e f
arr.splice(4,1);
arr.splice(5,1);//這時候數(shù)組長度是5。想刪除第六個元素當(dāng)然是不可能的
alert(arr);//a,b,c,d,e f 沒有刪掉
//本來想刪除 e f
arr.splice(4,1);
arr.splice(5,1);//這時候數(shù)組長度是5。想刪除第六個元素當(dāng)然是不可能的
alert(arr);//a,b,c,d,e f 沒有刪掉
也就是在批量刪除的時候,其實數(shù)組長度也在發(fā)生變化。幾番調(diào)試糾結(jié)之后,發(fā)現(xiàn)如果從一個數(shù)組元素的后面刪除到前面,這樣不管長度怎么變化都沒有關(guān)系了 。
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
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并不是規(guī)規(guī)矩矩的排序的,于是首先想到是不是可以先將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數(shù)組中下表為5,1,3的數(shù)組
alert(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數(shù)組中下表為5,1,3的數(shù)組
alert(removeBatch2(arr,toDeleteIndexes));
上面的函數(shù)能批量刪除元素,下面這種方法(方法二)也可行:
//批量刪除指定下標(biāo)的數(shù)據(jù)元素
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數(shù)組中下表為5,1,3的數(shù)組
alert(removeBatch(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數(shù)組中下表為5,1,3的數(shù)組
alert(removeBatch(arr,toDeleteIndexes));
這種方法是一種典型的用空間復(fù)雜度換取時間復(fù)雜度。這兩種方法究竟孰優(yōu)孰劣,可以簡單的計算一下循環(huán)次數(shù)。(n代表arr長度,m代表toDeleteIndexes長度)
方法一的運(yùn)算次數(shù):通常sort最多是n*(n-1)/2 次。后面循環(huán)了m*( n*(n-1)/2)。splice應(yīng)該也循環(huán)了begin次數(shù)。所以總的運(yùn)算次數(shù)應(yīng)該是(m+1)*n*(n-1)/2次
方法二的運(yùn)算次數(shù):n*m/2 for (var j=0;j<toDeleteIndexes.length ; j++){if(i==toDeleteIndexes[j]){needDelete=true; break;} 算m/2次。
方法二需要重新申明一個數(shù)組,占內(nèi)存應(yīng)該會大些。
關(guān)于算法方面的結(jié)論,都是估算,還請讀者指點(diǎn)。
總的來說,對于有確定的排序下標(biāo)的批量刪除,速度是最快的,不需要對下標(biāo)排序。大家有更好的方法,歡迎交流。
posted on 2010-12-29 15:58 衡鋒 閱讀(3043) 評論(4) 編輯 收藏 所屬分類: javascript 、Web開發(fā)