2009-12-31 29 views
15

Với một mảng let foo = [|1;2;3;4|] Tôi có thể sử dụng bất kỳ thao tác nào sau đây để trả về một lát từ một mảng.Chức năng giống như Slice từ một Danh sách trong F #

foo.[..2] 
foo.[1..2] 
foo.[2..] 

Tôi có thể làm điều tương tự cho Danh sách let foo2 = [1;2;3;4]? Khi tôi thử cú pháp giống như mảng tôi nhận được error FS00039: The field, constructor or member 'GetSlice' is not defined.

Phương pháp ưa thích để nhận được một phần con của Danh sách là gì và tại sao chúng không được xây dựng để hỗ trợ GetSlice?

Trả lời

36

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.skipSeq.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] 
8

F # 4.0 sẽ cho phép cắt cú pháp cho các danh sách (link).

Lý do là here:.

Chiếc F # danh sách loại đã hỗ trợ một nhà điều hành chỉ số, xs [3]. Điều này được thực hiện mặc dù thực tế là danh sách được liên kết danh sách trong F # - danh sách chỉ là như vậy thường được sử dụng trong F # rằng trong F # 2.0 nó đã được quyết định hỗ trợ này.

Vì cú pháp chỉ mục được hỗ trợ, nên có nghĩa là cũng hỗ trợ cú pháp F # slicing, ví dụ: xs. [3..5]. Nó rất lạ khi phải chuyển sang kiểu mảng để sử dụng slicing, nhưng bạn không phải thực hiện chuyển đổi đó để lập chỉ mục.

Tuy nhiên, Juliet trả lời, nói rằng, phần lớn thời gian cắt một danh sách là cách tiếp cận sai, vẫn đúng. Vì vậy, hãy khôn ngoan khi sử dụng tính năng này.

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