F# 基于F中的条件重新格式化列表#
我是函数式编程新手,目前正在F#从事一个项目 我运行了一个问题:我有一个类型为F# 基于F中的条件重新格式化列表#,f#,functional-programming,f#-4.0,F#,Functional Programming,F# 4.0,我是函数式编程新手,目前正在F#从事一个项目 我运行了一个问题:我有一个类型为stringlist的列表,我需要基于每个stringlist的中间元素构建单独的列表。例如: [["1";"b";"2"];["2";"a";"0"];["3";"b";"4"];["3";"a";"5"]] 将分为两个类似于以下内容的列表: let a = [["2";"0"];["3";"5"]] let b = [["1";"2"];["3";"4"]] 我尝试使用让a=[for[x;y;z]在myList
stringlist
的列表,我需要基于每个stringlist
的中间元素构建单独的列表。例如:
[["1";"b";"2"];["2";"a";"0"];["3";"b";"4"];["3";"a";"5"]]
将分为两个类似于以下内容的列表:
let a = [["2";"0"];["3";"5"]]
let b = [["1";"2"];["3";"4"]]
我尝试使用让a=[for[x;y;z]在myList中产生[x;z]
但是我在添加y=“b”的条件时遇到了问题
如果您试图按列表的中间元素拆分列表,将不胜感激。当您的列表没有3个元素时,预期的行为是什么
let myList = [["1";"b";"2"];["2";"a";"0"];["3";"b";"4"];["3";"a";"5"]]
let a = [for [x;y;z] in myList do if y="a" then yield [x;z]]
let b = [for [x;y;z] in myList do if y="b" then yield [x;z]]
在Functional_S提供的答案中,您将看到中[x;y;z]
下的摇摆线
let a = [for [x;y;z] in myList do if y="a" then yield [x;z]]
编译器说“模式匹配不完整”。而不是现在添加额外的检查来处理空列表,长度2等的列表,考虑改变您的数据类型的设计。如果数据始终包含3个元素,则使用正好包含3个元素的数据结构。在这里,元组是一个明显的选择,或者使用记录
let myList = [ ("1","b","2"); ("2","a","0"); ("3","b","4"); ("3","a","5") ]
let splitByMiddle =
myList
|> List.groupBy (fun (_, middle, _) -> middle)
|> List.map (fun (middle, elems) -> middle, elems |> List.map (fun (l, _, r) -> l, r))
如果在interactive中执行此操作,您将获得:
val splitByMiddle : (string * (string * string) list) list =
[("b", [("1", "2"); ("3", "4")]); ("a", [("2", "0"); ("3", "5")])]
另一种选择是:
let splitByMiddle =
myList
|> List.map (fun (l, middle, r) -> middle, (l, r))
|> List.groupBy fst
|> List.map (fun (middle, elems) -> middle, elems |> List.map snd)
我发现,当您使用数据类型尽可能地对域进行建模时,F#的性能确实达到了顶峰。在像Matlab这样的语言中,向量和矩阵是你的头号工作马,你会把所有的东西都放到列表中。但是在F#中,定义数据类型的成本非常低(就键入工作而言)——一旦您这样做了,编译器就是您最好的朋友,可以提醒您代码没有涵盖的可能的极端情况
在这种情况下:我看到所有中间元素都是字符串,而左/右元素是整数。也许你的领域更适合用这个记录建模
type R =
{
Left: int
Right: int
Middle: string
}
let create (l, m, r) = { Left = l; Right = r; Middle = m}
let myList = [ create(1,"b",2); create(2,"a",0); create(3,"b",4); create(3,"a",5) ]
let splitByMiddle =
myList
|> List.groupBy (fun r -> r.Middle)
这将为您提供:
val splitByMiddle : (string * R list) list =
[("b", [{Left = 1;
Middle = "b";
Right = 2;}; {Left = 3;
Middle = "b";
Right = 4;}]); ("a", [{Left = 2;
Middle = "a";
Right = 0;}; {Left = 3;
Middle = "a";
Right = 5;}])]
非常感谢你。我一直未能使用
然后
。问题解决了。