问题描述
使用数组 let foo = [|1;2;3;4|]
我可以使用以下任一方法从数组返回切片.
With an array let foo = [|1;2;3;4|]
I can use any of the following to return a slice from an array.
foo.[..2]
foo.[1..2]
foo.[2..]
如何为 List let foo2 = [1;2;3;4]
做同样的事情?当我尝试与数组相同的语法时,我得到 error FS00039: The field, constructor or member 'GetSlice' is not defined.
How can I do the same thing for List let foo2 = [1;2;3;4]
? When I try the same syntax as the array I get error FS00039: The field, constructor or member 'GetSlice' is not defined.
获取列表子部分的首选方法是什么?为什么它们不支持 GetSlice?
What's the preferred method of getting a subsection of a List and why aren't they built to support GetSlice?
推荐答案
我们先把最后一个问题放在最后,把第一个问题放在最后:
Let's make the last question first and the first question last:
为什么列表不支持 GetSlice
列表被实现为链接列表,因此我们没有对它们进行有效的索引访问.相对而言,foo.[|m..n|]
对数组花费O(nm)
时间,等效语法为O(n)
> 在名单上的时间.这是一个非常大的问题,因为它使我们无法在绝大多数有用的情况下有效地使用切片语法.
Lists are implemented as linked lists, so we don't have efficient indexed access to them. Comparatively speaking, foo.[|m..n|]
takes O(n-m)
time for arrays, an equivalent syntax takes O(n)
time on lists. This is a pretty big deal, because it prevents us from using slicing syntax efficiently in the vast majority of cases where it would be useful.
例如,我们可以在线性时间内将数组切割成大小相等的部分:
For example, we can cut up an array into equal sized pieces in linear time:
let foo = [|1 .. 100|]
let size = 4
let fuz = [|for a in 0 .. size .. 100 do yield foo.[a..a+size] |]
但是如果我们使用列表呢?每次调用foo.[a..a+size]
都会花费越来越长的时间,整个操作是O(n^2)
,非常不合适为了这份工作.
But what if we were using a list instead? Each call to foo.[a..a+size]
would take longer and longer and longer, the whole operation is O(n^2)
, making it pretty unsuitable for the job.
大多数时候,对列表进行切片是错误的方法.我们通常使用模式匹配来遍历和操作列表.
Most of the time, slicing a list is the wrong approach. We normally use pattern matching to traverse and manipulate lists.
切片列表的首选方法?
在可能的情况下,尽可能使用模式匹配.否则,您可以依靠 Seq.skip
和 Seq.take
为您切割列表和序列:
Wherever possible, use pattern matching if you can. Otherwise, you can fall back on Seq.skip
and Seq.take
to cut up lists and sequences for you:
> [1 .. 10] |> Seq.skip 3 |> Seq.take 5 |> Seq.toList;;
val it : int list = [4; 5; 6; 7; 8]
这篇关于从 F# 中的列表切片功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!