Phương pháp ưa thích để nhận được một phần con của Danh sách và tại sao không được xây dựng để hỗ trợ GetSlice?
Hãy làm cho câu hỏi cuối cùng đầu tiên và câu hỏi đầu tiên cuối cùng:
Tại sao danh sách không hỗ trợ GetSlice
Danh sách được thực hiện như danh sách liên kết, vì vậy chúng tôi không có hiệu quả lập chỉ mục truy cập vào chúng. Nói cách khác, foo.[|m..n|]
mất O(n-m)
thời gian cho mảng, một cú pháp tương đương mất O(n)
thời gian trên danh sách. Đây là một thỏa thuận khá lớn, bởi vì nó ngăn cản chúng ta sử dụng cú pháp slicing hiệu quả trong phần lớn các trường hợp nó sẽ hữu ích.
Ví dụ, chúng ta có thể cắt ra một mảng thành từng miếng có kích thước tương đương trong thời gian tuyến tính:
let foo = [|1 .. 100|]
let size = 4
let fuz = [|for a in 0 .. size .. 100 do yield foo.[a..a+size] |]
Nhưng nếu chúng ta đang sử dụng một danh sách để thay thế? Mỗi cuộc gọi đến foo.[a..a+size]
sẽ mất nhiều thời gian hơn và lâu hơn, toàn bộ hoạt động là O(n^2)
, khiến cho nó không phù hợp với công việc.
Hầu hết thời gian, việc cắt một danh sách là cách tiếp cận sai. Chúng tôi thường sử dụng đối sánh mẫu để duyệt qua và điều khiển danh sách.
Phương pháp ưu tiên để cắt danh sách?
Bất cứ nơi nào có thể, hãy sử dụng đối sánh mẫu nếu bạn có thể. Nếu không, bạn có thể rơi trở lại trên Seq.skip
và Seq.take
cắt lập danh sách và trình tự cho bạn:
> [1 .. 10] |> Seq.skip 3 |> Seq.take 5 |> Seq.toList;;
val it : int list = [4; 5; 6; 7; 8]