目前我有一个函数可以将列表中的每个列表的第一个元素(浮点数)返回到单独的列表中。
let firstElements list =
match list with
| head::_ -> head
| [] -> 0.00
我的问题是,我如何扩展它以将同一索引中的元素返回到不同的列表中,而我不知道这个列表有多长?例如
let biglist = [[1;2;3];[4;5;6];[7;8;9]]
如果我不知道这个列表的长度,那么最有效和最安全的方法是什么
[[1;4;7];[2;5;8];[3;6;9]]
答案 0 :(得分:3)
List.transpose
添加到FSharp.Core
let biglist = [[1;2;3];[4;5;6];[7;8;9]]
let res = biglist |> List.transpose
//val res : int list list = [[1; 4; 7]; [2; 5; 8]; [3; 6; 9]]
答案 1 :(得分:2)
您可以使用最近添加的List.transpose
功能。但是,自己创造这样的功能总是好的。如果您想自己解决问题,请考虑一般算法来解决您的问题。一个是。
这可能是解决问题的第一次尝试。此时,功能名称已组成。
let transpose lst =
if allEmpty lst
then // Some Default value, we don't know yet
else ...
else
分支如下所示。首先,我们要选择每个元素的第一个元素。我们设想一个执行此任务的函数pickFirsts
。所以我们可以写pickFirsts lst
。结果是一个列表,它本身是新列表的第一个元素。
新列表是剩余列表的结果。首先,我们再次想象一个函数,它会删除每个子列表dropFirsts lst
的第一个元素。在该列表中,我们需要重复步骤1)。我们通过递归调用transpose
来做到这一点。
总的来说,我们得到:
let rec transpose lst =
if allEmpty lst
then // Some Default value, we don't know yet
else (pickFirsts lst) :: (transpose (dropFirsts lst))
此时我们可以想到默认值。 transpose
需要返回一个值,如果它以空列表的空列表结束。当我们使用transpose
的结果向其添加元素时。它的结果必须是list
。最好的默认值是一个空列表。所以我们最终得到了。
let rec transpose lst =
if allEmpty lst
then []
else (pickFirsts lst) :: (transpose (dropFirsts lst))
接下来,我们需要实现其余功能allEmpty
,pickFirsts
和dropFirsts
。
pickFirst
很简单。我们需要迭代每个元素,并且必须返回第一个值。我们通过List.head
得到列表的第一个值,并迭代它并将每个元素转换为新列表是List.map
的作用。
let pickFirsts lst = List.map List.head lst
dropFirsts
需要对每个元素进行迭代,只需删除第一个元素,换句话说就是保留列表的剩余/尾部。
let dropFirsts lst = List.map List.tail lst
剩下的allEmpty
是一个谓词,如果我们有一个空的列表列表,则返回true / false。返回值为bool
,我们需要另一个允许返回另一个类型的函数是列表。这通常是使用List.fold
的原因。实现可能如下所示:
let allEmpty lst =
let folder acc x =
match x with
| [] -> acc
| _ -> false
List.fold folder true lst
以true
作为默认值开头。只要找到空列表,它就会返回默认值不变。一旦找到一个元素,在任何列表中,它将返回false
(非空)作为新的默认值。
整个代码:
let allEmpty lst =
let folder acc x =
match x with
| [] -> acc
| _ -> false
List.fold folder true lst
let pickFirsts lst = List.map List.head lst
let dropFirsts lst = List.map List.tail lst
let rec transpose lst =
if allEmpty lst
then []
else (pickFirsts lst) :: (transpose (dropFirsts lst))
transpose [[1;2;3];[4;5;6];[7;8;9]]
另一种方法是将其变成二维可变阵列。还要做长度检查。进行转换并再次将可变数组作为不可变列表返回。