Làm cách nào để sao chép danh sách này sang danh sách khác trong javascript?

Bạn không thể sao chép một danh sách chỉ bằng cách gõ list2 = list1, bởi vì. list2 sẽ chỉ là tham chiếu đến list1 và những thay đổi được thực hiện trong list1 cũng sẽ tự động được thực hiện trong list2

Có nhiều cách để tạo một bản sao, một cách là sử dụng phương thức Danh sách tích hợp sẵn copy()

Thí dụ

Tạo một bản sao của danh sách bằng phương thức copy()

thislist = ["apple", "banana", "cherry"]
mylist = thislist. copy()
print(mylist)

Tự mình thử »

Một cách khác để tạo một bản sao là sử dụng phương pháp tích hợp sẵn list()

Thí dụ

Tạo một bản sao của danh sách bằng phương thức list()

thislist = ["apple", "banana", "cherry"]
mylist = list(thislist)
print(mylist)Tự mình thử »




Các phương pháp sao chép một đố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 đề. Bạn cần một bản sao sâu nếu một đối tượng JavaScript chứa các đối tượng khác

Ảnh của João Silas trên Bapt Bản sao nông là gì?

M tạo một bản sao nông của một mảng hoặc đối tượng có nghĩa là tạo các tham chiếu mới đến các giá trị nguyên thủy bên trong đối tượng, sao chép chúng.

Điều đó có nghĩa là những thay đổi đối với mảng ban đầu sẽ không ảnh hưởng đến mảng đã sao chép, đó là điều sẽ xảy ra nếu chỉ tham chiếu đến mảng đã được sao chép (chẳng hạn như sẽ xảy ra với toán tử gán =)

Một bản sao nông đề cập đến thực tế là chỉ có một cấp độ được sao chép và điều đó sẽ hoạt động tốt đối với một mảng hoặc đối tượng chỉ chứa các giá trị nguyên thủy

Đối với các đối tượng và mảng chứa các đối tượng hoặc mảng khác, việc sao chép các đối tượng này yêu cầu một bản sao sâu. Mặt khác, những thay đổi được thực hiện đối với các tham chiếu lồng nhau sẽ thay đổi dữ liệu được lồng trong đối tượng hoặc mảng ban đầu

Trong bài viết này, tôi mô tả 4 phương pháp tạo bản sao nông và sau đó là 5 phương pháp tạo bản sao sâu trong JavaScript

Ảnh của Jakob Owens trên Bapt Bản sao nông sử dụng ________ 10

1. Toán tử trải rộng (list20) là một cách thuận tiện để tạo một bản sao nông của một mảng hoặc đối tượng — khi không có lồng nhau, nó hoạt động rất tốt.

Như đã trình bày ở trên, toán tử trải rộng rất hữu ích để tạo các thể hiện mới của mảng không hoạt động ngoài ý muốn do các tham chiếu cũ. Do đó, toán tử trải rộng rất hữu ích để thêm vào một mảng trong Trạng thái phản ứng

Ảnh của Donald Giannatti trên bản sao UnsplashShallow sử dụng list22

2. Đối với các mảng cụ thể, sử dụng phương thức list23 tích hợp hoạt động giống như toán tử trải rộng — tạo một bản sao nông của một cấp.

Ảnh của Antonio Garcia trên bản sao UnsplashShallow sử dụng. giao phó()

3. Cùng một loại bản sao nông sẽ được tạo bằng cách sử dụng list24, có thể được sử dụng với bất kỳ đối tượng hoặc mảng nào.

Ảnh của Paweł Czerwiński trên UnsplashShallow sao chép các mảng bằng cách sử dụng list25

4. Một phương pháp khác để sao chép một mảng JavaScript là sử dụng list26, cũng sẽ tạo một bản sao nông, như minh họa trong ví dụ này.

Nếu một đối tượng hoặc mảng chứa các đối tượng hoặc mảng khác, các bản sao nông sẽ hoạt động ngoài dự kiến, bởi vì các đối tượng lồng nhau không thực sự được sao chép

Đối với các đối tượng được lồng sâu, sẽ cần một bản sao sâu. Tôi giải thích tại sao dưới đây

Ảnh của brabus biturbo trên BaptCoi chừng Gotcha lồng sâu

Bật mặt khác, khi các đối tượng JavaScript bao gồm các mảng được lồng sâu vào nhau, toán tử trải rộng chỉ sao chép cấp độ đầu tiên bằng một tham chiếu mới, nhưng các giá trị sâu hơn vẫn được liên kết với nhau.

Để giải quyết vấn đề này, cần phải tạo một bản sao sâu, trái ngược với một bản sao nông. Bản sao sâu có thể được tạo bằng lodash, rfdc hoặc R. clone() phương pháp từ thư viện lập trình chức năng Ramda. Tôi khám phá các bản sao sâu tiếp theo

Ảnh của Landon Martin trên Bapt Bản sao sâu là gì?

F hoặc các đối tượng và mảng chứa các đối tượng hoặc mảng khác, việc sao chép các đối tượng này yêu cầu một bản sao sâu. Mặt khác, những thay đổi được thực hiện đối với các tham chiếu lồng nhau sẽ thay đổi dữ liệu được lồng trong đối tượng hoặc mảng ban đầu.

Điều này được so sánh với một bản sao nông, hoạt động tốt đối với một đối tượng hoặc mảng chỉ chứa các giá trị nguyên thủy, nhưng sẽ không thành công đối với bất kỳ đối tượng hoặc mảng nào có các tham chiếu lồng nhau đến các đối tượng hoặc mảng khác

Hiểu được sự khác biệt giữa list27 và list28 có thể giúp thấy rõ sự khác biệt giữa bản sao nông và bản sao sâu, vì toán tử đẳng thức nghiêm ngặt (list200) cho thấy các tham chiếu lồng nhau giống nhau

Tôi sẽ đề cập đến 5 phương pháp tạo bản sao sâu (hoặc bản sao sâu). lodash, Ramda, một chức năng tùy chỉnh, list201 / list202 và list203

Ảnh của mya thet khine trên UnsplashDeep copy bằng lodash

1. Thư viện lodash là cách phổ biến nhất mà các nhà phát triển JavaScript tạo bản sao sâu. Nó rất dễ sử dụng.

Tên của Lodash xuất phát từ thư viện được gọi là dấu gạch dưới (list204), "dấu gạch ngang thấp" hoặc viết tắt là lodash

Ảnh của Annie Spratt trên BaptBản sao sâu với Ramda

2. Thư viện lập trình chức năng Ramda bao gồm phương thức list205, tạo bản sao sâu của một đối tượng hoặc mảng.

Lưu ý rằng list206 từ Ramda tương đương với list207 cho lodash, vì Ramda không có phương thức trợ giúp bản sao nông

Ảnh của Roi Dimor trên UnsplashDeep copy với chức năng tùy chỉnh

3. Khá dễ dàng để viết một hàm JavaScript đệ quy sẽ tạo một bản sao sâu của các đối tượng hoặc mảng lồng nhau. Đây là một ví dụ.

Lưu ý rằng tôi cũng cần kiểm tra giá trị rỗng vì giá trị null của list208 là “đối tượng. ”

Ảnh của Scott Webb trên UnsplashDeep sao chép bằng JSON. phân tích/xâu chuỗi

4. Nếu dữ liệu của bạn phù hợp với thông số kỹ thuật (xem bên dưới), thì list209 theo sau là list200 sẽ sao chép sâu đối tượng của bạn.

“Nếu bạn không sử dụng các list201, các hàm, list202, list203, [NaN], RegExps, Maps, Sets, Blobs, FileLists, ImageData, Mảng thưa thớt, Mảng đã nhập hoặc các loại phức tạp khác trong đối tượng của bạn, thì một lớp lót rất đơn giản để đào sâu . list204” — Dan Dascalescu trong câu trả lời StackOverflow của anh ấy

Để chứng minh một số lý do tại sao phương pháp này thường không được khuyến nghị, đây là một ví dụ về việc tạo một bản sao sâu bằng cách sử dụng list204

Một chức năng tùy chỉnh hoặc các thư viện được đề cập có thể tạo một bản sao sâu mà không cần phải lo lắng về loại nội dung, mặc dù các tham chiếu vòng tròn sẽ làm hỏng tất cả chúng

Tiếp theo, tôi thảo luận về một thư viện cực nhanh có tên là list206 có thể xử lý các tham chiếu vòng tròn trong khi vẫn nhanh như chức năng sao chép sâu tùy chỉnh

Ảnh của Scott Webb trên Bapt Sao chép sâu thật nhanh?

5. Để có hiệu suất tốt nhất, thư viện list203 (Really Fast Deep Clone) sẽ sao chép sâu nhanh hơn khoảng 400% so với list209 của lodash.

list220 sao chép tất cả các loại JSON. •list221•list222•list223•list224•list225

Với sự hỗ trợ bổ sung cho. •list201 (được sao chép) •list202 (được sao chép) •list228 (được tham chiếu) •list229 (được tham chiếu) •list230 (được tham chiếu) •list231 (được sao chép vào đối tượng bình thường)

Tất cả các loại khác có giá trị đầu ra khớp với đầu ra của list232. ” —Tài liệu rfdc

Sử dụng list206 khá đơn giản, giống như các thư viện khác

Thư viện list206 hỗ trợ tất cả các loại và cũng hỗ trợ tham chiếu vòng với cờ tùy chọn làm giảm hiệu suất khoảng 25%

Tham chiếu vòng tròn sẽ phá vỡ các thuật toán sao chép sâu khác được thảo luận

Một thư viện như vậy sẽ hữu ích nếu bạn đang xử lý một đối tượng lớn, phức tạp, chẳng hạn như một đối tượng được tải từ các tệp JSON có kích thước từ 3MB-15MB

Dưới đây là các điểm chuẩn, cho thấy list206 nhanh hơn khoảng 400% khi xử lý các đối tượng lớn như vậy

list236— Tài liệu rfdc

  • Thư viện list206 (Really Fast Deep Clone) có trên GitHub và npm

davidmarkclements/rfdc

Bản sao sâu thực sự nhanh. Đóng góp cho sự phát triển của davidmarkclements/rfdc bằng cách tạo một tài khoản trên GitHub

github. com

rfdc

Bản sao sâu thực sự nhanh

www. npmjs. com

Ảnh của Scott Webb trên UnsplashPerformance of JavaScript Copy Algorithms

Trong số các thuật toán sao chép khác nhau, các bản sao nông là nhanh nhất, tiếp theo là các bản sao sâu sử dụng chức năng tùy chỉnh hoặc list206.

“Bản sao sâu theo hiệu suất. Xếp hạng từ tốt nhất đến tồi tệ nhất

Chỉ định lại “list239” (mảng chuỗi, mảng số — chỉ)

Slice (mảng chuỗi, mảng số — chỉ)

Nối (mảng chuỗi, mảng số — chỉ)

chức năng tùy chỉnh. sao chép vòng lặp for hoặc đệ quy

[Ghi chú của tác giả. list240 sẽ ở đây, nhanh như chức năng tùy chỉnh]

list241 của jQuery

list242 (mảng chuỗi, mảng số, mảng đối tượng — chỉ)

dấu gạch dưới. js's list243 (mảng chuỗi, mảng số — chỉ)

Lo-Dash's list244” — Tim Montague trong câu trả lời StackOverflow của anh ấy

Việc sử dụng list245/list246 sẽ tạo ra các vấn đề xung quanh các loại dữ liệu, vì vậy nên sử dụng list206 — trừ khi bạn muốn viết một hàm tùy chỉnh

Ảnh của Keila Hötzel trên BaptKết luận. Cách sao chép sâu trong JavaScript

thực sự khá dễ dàng để tránh phải sao chép sâu trong JavaScript — nếu bạn không bao giờ có thể lồng các đối tượng và mảng vào trong nhau.

Bởi vì trong trường hợp đó — khi không có lồng nhau và các đối tượng cũng như mảng chỉ chứa các giá trị nguyên thủy — tạo một bản sao nông với toán tử trải rộng (list20), list22 và list250 đều hoạt động tốt

Tuy nhiên, trong thế giới thực, nơi các đối tượng có các mảng bên trong chúng hoặc ngược lại, thì một bản sao sâu sẽ cần được sử dụng. Tôi khuyên dùng list203 cho các bản sao sâu

(Lưu ý rằng một số người cũng có thể đề xuất sử dụng list202 theo sau là list201, nhưng đó không phải là cách đáng tin cậy để tạo một bản sao sâu. )