F#和#x2013;用累加器映射列表
一般来说,我对F#和函数式编程是新手。给定一个场景,您希望迭代一个序列或字符串列表,并使用累加器将其映射到不同类型的新列表,正确的函数方法是什么?我可以通过使用可变变量在F#中实现这一点,但我正在努力找到合适的函数来实现这一点。我想这和地图很相似,但有国家的概念 换句话说,我想将字符串列表转换为win forms单选按钮列表,但对于每个新按钮,我想在之前的y坐标上添加20。比如:F#和#x2013;用累加器映射列表,f#,F#,一般来说,我对F#和函数式编程是新手。给定一个场景,您希望迭代一个序列或字符串列表,并使用累加器将其映射到不同类型的新列表,正确的函数方法是什么?我可以通过使用可变变量在F#中实现这一点,但我正在努力找到合适的函数来实现这一点。我想这和地图很相似,但有国家的概念 换句话说,我想将字符串列表转换为win forms单选按钮列表,但对于每个新按钮,我想在之前的y坐标上添加20。比如: new RadioButton(Text=str,Location=new Point(20,y+20),Width
new RadioButton(Text=str,Location=new Point(20,y+20),Width=350)
您可以通过引用访问和更改变量
let x = ref 0
x := !x + 5
new Point(20,!x+20)
您可以在闭包中使用这样的变量
您还可以使用mapi
:
并基于
i
相似新点(20,i*20+20)
向y添加值。您可以使用列表。折叠:
open System.Drawing
open System.Windows.Forms
let getButtons () =
let strings = ["a"; "b"; "c"]
let (_, pointsRev) = List.fold (fun (offset, l) s -> (offset+20, (new RadioButton(Text=s, Location = new Point(20, offset), Width = 350))::l)) (0, []) strings
pointsRev |> List.rev
状态是一对,包含当前偏移量和当前输出列表。输出列表是按相反的顺序构建的,因此必须在末尾反转
您也可以使用Seq.map2:
let points = Seq.map2 (fun offset s -> new RadioButton(Text=s, Location = new Point(20, offset)) (Seq.initInfinite ((*)20)) strings |> List.ofSeq
使用List.fold
是一个好主意(请参阅公认的答案)
作为一名F#初学者,我将折叠拆分为一个单独的函数,并重命名了一些变量,以便更清楚地理解事情。这似乎有效:
let buttonNames = ["Button1Name"; "Button2Name"]
let createRadioButton (offset, radioButtons) name =
let newRadioButton = new RadioButton(Text=name, Location=new Point(20, offset), Width=350)
(offset + 20, newRadioButton::radioButtons)
let (_, buttonsReversed) = buttonNames |> List.fold createRadioButton (0, [])
let buttons = buttonsReversed |> List.rev
啊,我没有看到mapi,谢谢。关于ref方法,这仍然不是一种常见的“功能”方法,对吗?在学习过程中,我试图强迫自己避免旧习惯。正确。但我个人还是喜欢我的旧习惯。很好。对于像我这样的新手(语法仍然混乱),我一开始会很费劲,但我明白了。@Lee,谢谢,这对我帮助很大,但只是为了你的信息,列表。fold
示例目前还没有编译(即使声明了字符串
列表)。你能编辑一下吗?