如何使用 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)
相同,但我们不需要使用 h
和 t
,因此将无关占位符 _
代替。
第二个 ::
确保列表的列表 (listoflists) 非空或 (h::t)::c
= (head of listoflists)::listoflists 的尾部 所以 h::t
是第一行,c
是所有其他行。
(_::_)::_ <=> (headRow0::tailRow0)::tailRows
具有以下数据(随机字符串):
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)
相同,但我们不需要使用 h
和 t
,因此将无关占位符 _
代替。
第二个 ::
确保列表的列表 (listoflists) 非空或 (h::t)::c
= (head of listoflists)::listoflists 的尾部 所以 h::t
是第一行,c
是所有其他行。
(_::_)::_ <=> (headRow0::tailRow0)::tailRows