Xóa phần tử cụ thể khỏi mảng javascript mà không có chỉ mục

Tôi trình bày cách sử dụng .indexOf.splice để xóa một mục khỏi mảng. Sau đó, tôi so sánh hiệu suất với vòng lặp for và phương pháp .filter

Ảnh của Jackson Simmer trên Bapt

A câu hỏi thường gặp trong JavaScript là cách nhanh nhất để xóa một giá trị khỏi một mảng bằng các phương thức Javascript tích hợp [vanilla JS].

Nói cách khác, cách nhanh nhất để sửa đổi mảng không còn bao gồm một giá trị cụ thể

Bài viết này kiểm tra hiệu suất của 4 phương pháp khác nhau để xóa một mục cụ thể khỏi một mảng trong JavaScript

Xóa một mục khỏi Mảng

Một cách để giải quyết vấn đề này là sử dụng Array.prototype.indexOf[] để tìm chỉ mục của giá trị, sau đó sử dụng Array.prototype.splice[] để xóa mục đó

Lưu ý rằng .indexOf trả về -1 nếu không tìm thấy chỉ mục, nhưng .splice diễn giải chỉ mục -1 là mục cuối cùng trong mảng, giống như .indexOf2

Đoạn mã sau sử dụng toán tử dấu chấm hỏi .indexOf3 là tương đương

Bạn cũng có thể viết một lớp lót nếu bạn thực sự không bận tâm đến hiệu suất của việc tìm kiếm toàn bộ mảng hai lần nếu giá trị được tìm thấy

Tất cả các phương thức này chỉ xóa phiên bản đầu tiên của giá trị đã cho

Tôi sẽ thảo luận về các tùy chọn để xóa tất cả các mục phù hợp sau trong bài viết này

Còn vòng lặp for thì sao?

A tùy chọn hoàn toàn tốt để xóa một mục khỏi mảng là sử dụng vòng lặp for, mặc dù mã của bạn có thể khó đọc hơn.

Để làm cho nó tương đương với việc sử dụng .indexOf và chỉ xóa phiên bản đầu tiên, tôi đã sử dụng một biến để theo dõi xem giá trị đã bị xóa hay chưa

Sau đây sẽ loại bỏ tất cả các phiên bản bằng cách sử dụng .indexOf.splice

Và phần sau đây sẽ xóa tất cả các phiên bản bằng vòng lặp for

Cái nào nhanh hơn?

P thử nghiệm hiệu suất bằng cách sử dụng các trường hợp thử nghiệm jsPerf này cho thấy sự khác biệt lớn giữa hai phương pháp loại bỏ một mục khỏi một mảng.

Sử dụng vòng lặp .splice60 xuất hiện 2. Nhanh gấp 5 lần so với .indexOf.splice

Sự khác biệt này được phóng đại khi loại bỏ tất cả các phiên bản của giá trị phù hợp mà tôi đã thử nghiệm trong các trường hợp thử nghiệm jsPerf này

Như bạn có thể thấy, vòng lặp .splice60 xuất hiện nhanh hơn gấp 5 lần so với vòng lặp .splice64 sử dụng .indexOf.splice theo cách thực sự kém hiệu quả

Nhưng những kết quả này là sai lệch — bởi vì bộ xử lý vẫn đang xử lý 4000 thao tác mỗi mili giây [4.000.000 thao tác/giây]

Như bạn sẽ thấy sau này, .indexOf.splice thực sự có hiệu suất tốt hơn vòng lặp for khi xử lý các mảng lớn gồm 10.000 mục

Còn về .filter thì sao?

là một điểm hợp lý để đề cập đến phương thức .filter1 tích hợp, một trong những công cụ lập trình chức năng của JavaScript.

Dưới đây là một ví dụ về việc xóa tất cả các mục khỏi một mảng bằng cách sử dụng .filter, trả về một mảng đã lọc gồm các giá trị khớp với điều kiện đã cho

Về mặt tích cực, bộ lọc dẫn đến ít mã hơn nhiều. Nhưng nó nhanh như thế nào?

Trong các trường hợp thử nghiệm jsPerf này, tôi đã so sánh .filter với vòng lặp .filter4 siêu chậm bằng cách sử dụng .indexOf.splice và vòng lặp for siêu nhanh

Như bạn có thể thấy, .filter8 là một lựa chọn tốt — vòng lặp for nhanh hơn một chút, nhưng .filter8 vẫn ổn để loại bỏ tất cả các giá trị phù hợp khỏi một mảng

Cái nào nhanh nhất trong một mảng lớn?

Tất nhiên , dữ liệu trên kiểm tra các mảng nhỏ — và trình duyệt của tôi đang xử lý 4 triệu vòng lặp .filter4 mỗi giây. Nhiều tốc độ.

Điều gì sẽ xảy ra nếu chúng ta đang làm việc với một mảng lớn hơn, chẳng hạn như 10.000 mục?

Trong mảng 10.000 mục mà mục tiêu [số 5.000] chỉ được tìm thấy một lần, vòng lặp .filter4 với .indexOf.splice thực sự thắng

Đối với trường hợp sử dụng này, .filter là một kẻ thua cuộc lớn, vì vòng lặp for nhanh hơn khoảng 5 lần. Nhưng .indexOf.splice nhanh gấp đôi so với vòng lặp for

So sánh điều đó với một mảng 10.000 mục trong đó mục tiêu [số 5.000] được tìm thấy như mọi mục khác trong mảng. Kết quả hoàn toàn giống nhau

Suy nghĩ về ý nghĩa của những con số đó,. bộ lọc chỉ lấy 0. 25 mili giây để xử lý mảng 10.000 mục — vẫn khá nhanh

Thông điệp mang về nhà là đừng tham gia vào việc tối ưu hóa sớm

Sử dụng mã dễ đọc nhất có thể, sau đó chỉ tối ưu hóa nếu cần

Làm thế nào để tránh đột biến?

N lưu ý rằng .splice0 sửa đổi mảng tại chỗ, điều này thường tốt cho hiệu suất nhưng bạn có thể gặp tác dụng phụ [lỗi].

Xin lưu ý rằng việc sửa đổi một đối tượng, còn được gọi là thay đổi đối tượng, đôi khi được coi là thực hành mã xấu, vì khả năng xảy ra tác dụng phụ

Thậm chí còn có một plugin ESLint [eslint-plugin-immutable] vô hiệu hóa hoàn toàn tất cả các đột biến đối tượng — một ý tưởng hay để ngăn ngừa lỗi

Nhưng làm cách nào bạn có thể xóa một mục khỏi mảng mà không làm thay đổi mảng ban đầu?

Phương thức vòng lặp for đã tránh được đột biến, bởi vì bạn đang .splice2 các mục vào một mảng mới. Đây vốn dĩ là một bản sao nông của mảng

Nếu bạn cần tạo một bản sao sâu, do các đối tượng hoặc mảng lồng nhau bên trong một mảng, thì hãy xem bài viết của tôi về sao chép sâu mảng trong JavaScript

Cách sao chép sâu các đối tượng và mảng trong JavaScript

Các phương pháp sao chép đối tượng hoặc mảng thông thường chỉ tạo ra một bản sao nông, vì vậy các tham chiếu được lồng sâu là một vấn đề…

vừa phải. com

Sự kết luận

N Bây giờ bạn đã hiểu cách kết hợp .indexOf.splice để xóa mục nhập khỏi mảng JavaScript, do đó thay đổi mảng tại chỗ.

Để tránh thay đổi mảng, hãy tạo một bản sao nông hoặc sử dụng vòng lặp for

Vòng lặp for cũng là một lựa chọn tuyệt vời nếu bạn cần xóa mọi giá trị phù hợp khỏi một mảng— hoặc chỉ sử dụng .filter để lọc ra các mục phù hợp

Mặc dù kết hợp .indexOf.splice chậm hơn so với sử dụng vòng lặp for cho các mảng nhỏ, nhưng hiệu suất sẽ khác nhau đối với các mảng lớn hơn

Khuyến nghị của tôi là sử dụng các phiên bản dễ đọc nhất trong mã của bạn

  • .indexOf.splice để chỉ xóa phiên bản đầu tiên của một giá trị
  • .filter để xóa mọi phiên bản của một giá trị khỏi một mảng

Các phương thức đó sẽ tự ghi lại nhiều tài liệu hơn so với vòng lặp for, nơi bạn sẽ cần viết nhận xét giải thích mã của mình

Để có hiệu suất tốt nhất khi loại bỏ các mục khỏi mảng lớn, hãy xem xét .indexOf.splice, vì phương pháp đó có thể khá nhanh

Làm cách nào để xóa phần tử khỏi mảng trong JavaScript mà không cần chỉ mục?

Xóa phần tử khỏi mảng bằng cách nối nó. if [idx. = -1] mảng. mối nối[idx, 1];

Làm cách nào để xóa một phần tử cụ thể trong một mảng trong JavaScript?

Nếu bạn muốn xóa một phần tử khỏi mảng, bạn có thể sử dụng phương thức pop[] để xóa phần tử cuối cùng hoặc phương thức shift[] để xóa phần tử đầu tiên< . .

Chủ Đề