如何使用 F# 计算列表列表中列的最大值

how to calculate the max by column in a list of lists, with F#

具有以下数据(随机字符串):

let data =
    [
        ["shi"; "cjwocij"; "cjwijo"]
        ["abs"; "djw"; "djwjdwojdow"]
        ["djido"; "dkwpkw"; "dpfkpeoep"]
    ]

我想按列计算最大长度。 我可以将数据转换为长度列表的列表:

data |> List.map (fun r -> r |> List.map (fun x -> x.Length))
index   value
0       [ 3; 7; 6 ]
1       [ 3; 3; 11 ]
2       [ 5; 6; 9 ]

但最终我想将其减少为:

[5; 7; 11]

取每列的最大值

我想我可以折叠并以第一行为起点,但看起来会很复杂。

对于上下文:这是一个函数,它将采用网格并以适当的间距/格式显示它;所有行必须具有相同数量的元素。

你需要 List.transpose。这会将行变成列,反之亦然。

data 
|> List.map (fun r -> r |> List.map (fun x -> x.Length)) 
|> List.transpose
|> List.map List.max

val data : string list list =
  [["shi"; "cjwocij"; "cjwijo"]; ["abs"; "djw"; "djwjdwojdow"];
   ["djido"; "dkwpkw"; "dpfkpeoep"]]
val it : int list = [5; 7; 11]

这是转置的快速显式版本,可能会帮助(或阻碍?)你摸索这个:

let transpose lists =
    [0 .. (List.length (List.head lists)) - 1]
    |> List.map (fun col -> List.map (fun row -> List.item col row) lists )

这是完整性的递归版本,但我认为如果您是 F# 的新手,上面的内容会更清楚。

let rec transpose = function
    | (_::_)::_ as l -> List.map List.head l :: transpose (List.map List.tail l)
    | _ -> []

更新: 我在评论中回答了这个问题,但对于其他想知道第二个递归解决方案的人来说:

(_::_) 确保列表不为空。这与 (h::t) 相同,但我们不需要使用 ht,因此将无关占位符 _ 代替。

第二个 :: 确保列表的列表 (listoflists) 非空或 (h::t)::c = (head of listoflists)::listoflists 的尾部 所以 h::t是第一行,c是所有其他行。

(_::_)::_ <=> (headRow0::tailRow0)::tailRows