合并OCaml中的列表列 [英] Combining a column of lists in OCaml
问题描述
我想本质上在OCaml中转置矩阵(不使用递归或任何形式的循环)
I want to essentially transpose a matrix in OCaml (without using recursion or any sort of looping)
例如,如果我具有以下矩阵:[[1;2];[3;4]]
,
我想得到[[1;3];[2;4]]
的输出.
For example, if I have the following matrix: [[1;2];[3;4]]
,
I want to have the output of [[1;3];[2;4]]
.
到目前为止,我所做的是将原始矩阵分为几列:
What I have done so far is break the original matrix into individual columns:
//function that separates into cols
let separate li =
List.map (fun x -> [x]) li;;
我从另一个函数中调用此辅助函数:
I call this helper function from another function:
let trans x =
List.concat (List.map separate li) x;;
我当时以为这将以我想要的方式合并所有列,但最终以以下输出结束:[[1];[2];[3];[4]]
.
I was thinking this would combine all the columns the way I want to but rather, ended with the following output: [[1];[2];[3];[4]]
.
推荐答案
Assuming your list of lists is rectangular, this Standard ML code translates to OCaml as such:
let rec transpose xss =
match xss with
| [] -> []
| []::_ -> []
| _ -> List.map List.hd xss :: transpose (List.map List.tl xss)
它将提取第一列(List.map List.hd xss
),然后在删除已提取的列(List.map List.tl xss
)之后将其与其余列的提取递归组合.
It extracts the first column (List.map List.hd xss
) and recursively combines it with the extraction of the remaining columns, after having removed the already extracted column (List.map List.tl xss
).
此功能中仍然保留的显式递归不能轻易地被映射/折叠所替代,因为它们将一次寻址一行,而上面的递归方案会一次寻址所有行(一部分). 展开/变形 可能会让您更加幸运:
The explicit recursion that still remains in this function cannot easily be replaced by mapping / folding, since those would address one row at a time, where the recursion scheme above addresses (a part of) all rows at once. You might have more luck with unfolding / anamorphism:
let rec unfold f a =
match f a with
| Some (b, a') -> b :: unfold f a'
| None -> []
val unfold : ('a -> ('b * 'a) option) -> 'a -> 'b list = <fun>
其中'a
可能是您的输入行矩阵和'b
矩阵列的逐渐减少:
where 'a
could be the gradual reduction of your input row matrix, and 'b
the matrix columns:
let transpose =
unfold (function
| [] -> None
| []::_ -> None
| m -> Some (List.map List.hd m, List.map List.tl m))
这篇关于合并OCaml中的列表列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!