使用数组,let foo = [|1;2;3;4|]我可以使用以下任何一种方法从数组中返回一个切片.
foo.[..2]
foo.[1..2]
foo.[2..]
Run Code Online (Sandbox Code Playgroud)
我如何为List做同样的事情let foo2 = [1;2;3;4]?当我尝试与我得到的数组相同的语法时error FS00039: The field, constructor or member 'GetSlice' is not defined.
获取List子节的首选方法是什么?为什么它们不是为了支持GetSlice而构建的?
Jul*_*iet 42
获取List子节的首选方法是什么?为什么不构建为支持GetSlice?
让我们先说出最后一个问题,然后提出第一个问题:
为什么列表不支持GetSlice
列表是作为链表实现的,因此我们没有对它们进行有效的索引访问.相比较而言,数组foo.[|m..n|]需要O(n-m)时间,等效语法需要O(n)时间在列表上.这是一个非常重要的事情,因为它阻止我们在绝大多数有用的情况下有效地使用切片语法.
例如,我们可以在线性时间内将数组切割成相等大小的块:
let foo = [|1 .. 100|]
let size = 4
let fuz = [|for a in 0 .. size .. 100 do yield foo.[a..a+size] |]
Run Code Online (Sandbox Code Playgroud)
但是如果我们使用列表呢?每次通话foo.[a..a+size]都需要更长,更长,更长,整个操作O(n^2),使其非常不适合这项工作.
大多数情况下,切片列表是错误的方法.我们通常使用模式匹配来遍历和操作列表.
切片列表的首选方法?
尽可能使用模式匹配,如果可以的话.否则,您可以依赖Seq.skip并Seq.take为您剪切列表和序列:
> [1 .. 10] |> Seq.skip 3 |> Seq.take 5 |> Seq.toList;;
val it : int list = [4; 5; 6; 7; 8]
Run Code Online (Sandbox Code Playgroud)