others - F#转换嵌套列表

88 2

我想在F#中转换一个嵌套列表('a list list ),问题是,我不希望使用递归。

但是我发现,为了不使用递归,必须使用可变列表,在我看来这有点问题,不过,我尝试用一个循环和两个可变列表来实现它:


let transpose (llst : 'a list list) : 'a list list =


 let mutable lst = llst


 let mutable result = [List.map List.head lst]


 for i = 1 to lst.Length do


 lst <- List.map List.tail lst


 result <- List.append result [List.map List.head lst]


 result




let transpose (llst : 'a list list) : 'a list list = [List.ofArray (Array2D.init (llst.ToArray.GetLength 1) (llst.ToArray.GetLength 0) (fun x y -> llst.ToArray.[y,x]))]



第一个代码有效,但是我想要一个更简单的实现,没有循环或可变列表。第二个代码不起作用,因为函数List.ofArray只与[]一起工作,而不是[,]

我也尝试过


List.init (llst.[0].Length) (List.forall (fun SOMETHING) llst)



其中SOMETHING将包含一个函数,该函数接受两个子列表的第一列,然后删除第一列,(List.map List.head and List.map List.tail) . 也许使用List.map

时间: 原作者:

121 3

一种方法是采用递归定义并将它转换为非递归,例如,以下递归定义由这个答案和它使用列表推导进行调整:


let rec transpose xs = [


 match xs with


 | [] -> failwith"cannot transpose a 0-by-n matrix"


 | []::xs -> () 


 | xs -> 


 yield List.map List.head xs 


 yield! transpose (List.map List.tail xs) ]



这是tail递归,这使得它很容易转换为循环,你只需将参数xs变为可变的,还需要添加一个标志来终止循环:


let rec transpose xs = [


 let mutable xs = xs


 let mutable finished = false


 while not finished do


 match xs with


 | [] -> failwith"cannot transpose a 0-by-n matrix"


 | []::_ -> finished <- true


 | _ -> 


 yield List.map List.head xs 


 xs <- List.map List.tail xs ]



你可以将这些附加到可变列表,而不是(然后反转列表以便得到正确顺序的结果):


let rec transpose xs = 


 let mutable result = []


 let mutable xs = xs


 let mutable finished = false


 while not finished do


 match xs with


 | [] -> failwith"cannot transpose a 0-by-n matrix"


 | []::_ -> finished <- true


 | _ -> 


 result <- (List.map List.head xs) :: result


 xs <- List.map List.tail xs 


 List.rev result 



原作者:
...