List 拆分列表

List 拆分列表,list,f#,List,F#,我正在尝试编写一个方法,将列表一分为二。该函数应该返回两个列表的元组,该函数采用的参数是第一个列表上的#个项目,然后是列表。这就是我的意思 清单[1,2,3,4] 拆分(1,列表)->([1],[2,3,4]) 拆分(3,列表)->([1,2,3],[4]) 以下是我目前掌握的情况: let rec mysplit = function |(n,[])->([],[]) |(1,x::xs)->(x::[],xs) |(n,x::xs)-> mysplit(n-1

我正在尝试编写一个方法,将列表一分为二。该函数应该返回两个列表的元组,该函数采用的参数是第一个列表上的#个项目,然后是列表。这就是我的意思

清单[1,2,3,4]

拆分(1,列表)->([1],[2,3,4]) 拆分(3,列表)->([1,2,3],[4])

以下是我目前掌握的情况:

let rec mysplit = function
  |(n,[])->([],[])
  |(1,x::xs)->(x::[],xs)
  |(n,x::xs)->  mysplit(n-1,xs)

我不确定如何从递归调用中“捕获”元组。不知道在哪里有一个额外的let语句在那里临时保存我正在建立的列表。对该语言比较陌生,因此可以学习几种不同的方法。

简单的实现方法是:

let rec mysplit = function
  |(n,[])->([],[])
  |(1,x::xs)->(x::[],xs)
  |(n,x::xs)->  let (f, s) = mysplit(n-1,xs) in (x::f, s)
您还可以编写一个尾部递归版本:

let mysplit (n, l) = 
    let rec mysplit' n' (f, s) = function
    | [] -> (f, s)
    | (x::xs) as l' -> if n' = 0 then (f, l') else mysplit' (n'-1) (x::f, xs) xs

    let (f', s) = mysplit' n ([], []) l in (List.rev f', s)

Lee的回答向您展示了一个有效的解决方案,但要回答您的特定问题,您可以捕获返回给您的元组中的值,如下所示:

let before, after = mysplit (2, [1;2;3;4;5])
还可以使用此技巧在单个let语句中声明多个变量:

let i, j, k = (1, 2, 3)

斯基普和塔克是你的朋友。我认为当有直接方法时,不需要进行任何类型的匹配或递归调用

let split n l = (l |> Seq.take n, l |> Seq.skip n)
对于可能的边缘情况,如果列表中有
个元素,skip将返回一个空序列;如果序列中有
个元素,take将返回前n个元素

在TryFharp.org上用您的示例进行了尝试,效果如预期。

现在我称之为f#