2009-03-12 32 views
19

cách nhanh nhất để xóa một mục cụ thể từ giữa Mảng là gì()Cách nhanh nhất để xóa một mục từ giữa Array()

Mảng là một trong những lớn có Strings.

Tôi không muốn chỉ để thiết lập Array [5] = null, nhưng thay vì kích thước mảng nên được giảm một và mảng [5] sẽ có nội dung của mảng [6], vv

Trả lời

49

Đừng có bất kỳ tiêu chuẩn để hỗ trợ này, nhưng người ta sẽ giả định rằng nguồn gốc Array.splice phương pháp sẽ là nhanh nhất ...

Vì vậy, để loại bỏ các mục ở chỉ số 5:

array.splice(5, 1); 
+0

splice() thực sự là cách để đi, nhưng hãy nhớ rằng việc loại bỏ mọi thứ ở giữa sẽ chậm với các mảng lớn vì flash sẽ "di chuyển" các mục sau để lấp đầy khoảng trống. – grapefrukt

+3

Cũng lưu ý rằng việc xóa mọi thứ ở giữa một mảng trong khi chạy qua nó sẽ tàn phá trừ khi bạn đang chạy ngược. – Sean

+2

Lưu ý rằng điều này cũng sẽ làm việc cho JavaScript. – Grinn

23

Nếu bạn không quan tâm đến thứ tự của các mục trong mảng (nhưng chỉ muốn nó để có được 1 ngắn hơn) bạn có thể sao chép phần tử cuối cùng của mảng vào chỉ mục bị xóa, sau đó pop phần tử cuối cùng tắt.

array[index] = array[array.length-1]; 
array.pop(); 

Tôi đoán đây là nhanh hơn, CPU-thời gian-khôn ngoan, nếu bạn có thể lấy đi với sắp xếp lại mảng.

EDIT: Bạn nên chuẩn cho trường hợp cụ thể của mình; Gần đây tôi đã làm điều này, và nó chỉ nhanh hơn để ghép nối. (Có lẽ do Chrome đang không thực sự lưu trữ các mảng như một bộ đệm liên tục duy nhất.)

+1

Điều đó thực sự thông minh. Ridiculously nhanh hơn splice: http: // jsperf.com/remove-element-splice-vs-move-and-pop – MaiaVictor

+0

phương pháp cuối cùng trong jsperf làm hỏng trình duyệt của tôi ... – JustGoscha

+1

+1, cách một lớp lót: * mảng [index] = array.pop() * hoặc thậm chí * mảng [index] = mảng [array.length-- -1] * –

3

Array.splice()"thêm các yếu tố để và loại bỏ các yếu tố từ một mảng":

myArr.splice(indexToRemove, 1); // only removing one index, thus the 1 
1

Tùy thuộc vào trường hợp của bạn, bạn có thể xem xét sử dụng một từ điển thay vì một mảng nếu bạn muốn ưu tiên hiệu suất.

var dict:Dictionary = new Dictionary(); 

// The following value/key set should be customized so you can 
// get use of them in your specific case. 

dict[item1] = item1; 
dict[item2] = item2; 

... 

delete dict[item1]; 
2

Tôi đã thử nghiệm Array.prototype.splice() và thấy rằng nó rất chậm trên mảng lớn.

Cách xóa phần tử nhanh hơn nhiều là sao chép các phần tử bạn muốn giữ lại một mảng mới, trong khi bỏ qua các phần tử bạn muốn xóa. Sau khi sao chép xong, bạn chỉ cần ghi đè lên mảng cũ bằng mảng mới.

Trong thử nghiệm của tôi, tôi đã xóa mọi phần tử khác khỏi một mảng chứa 100.000 mục. Phép thử đã so sánh Array.prototype.splice() với các phương thức khác. Dưới đây là kết quả:

855 ms = splice 
    7 ms = manual copying without preserving the original array 
14 ms = manual copying with preserving the original array 

Dưới đây là các mã cho phương pháp cuối cùng:

var arrB = [], 
    i=varA.length, 
    j=0; 

// copy even items to a new array 
while(i > 0) { 
    i-=2; // skip two elements 
    arrB[j++] = arrA[i]; 
} 

// clear the old array 
arrA.splice(0, arrA.length); 

// copy values back to the old array 
// array is preserved (references to the array don't need to be updated) 
arrA.push.apply(arrA, arrB); 

Các thử nghiệm trong hành động có thể được tìm thấy trên jsFiddle: http://jsfiddle.net/sansegot/eXvgb/3/

Kết quả là khác nhiều so với khi bạn chỉ cần phải loại bỏ một vài mục - trong trường hợp này Array.prototype.splice() là nhanh hơn (mặc dù sự khác biệt không quá lớn)! Chỉ khi bạn cần phải gọi splice() nhiều lần nó có giá trị nó để thực hiện thuật toán tùy chỉnh. Thử nghiệm thứ hai, trong đó một số lượng hạn chế các thành phần cần xóa có thể được tìm thấy tại đây: http://jsfiddle.net/sansegot/ZeEFJ/1/

Các vấn đề liên quan