【问题标题】:F# – mapping a list with an accumulatorF# – 用累加器映射列表
【发布时间】:2014-03-12 12:24:47
【问题描述】:

我是 F# 和函数式编程的新手。给定一个场景,您想要迭代一个序列或字符串列表,并将其映射到不同类型的新列表,使用累加器,正确的函数方法是什么?我可以在 F# 中使用可变变量来实现这一点,但我正在努力寻找合适的函数来实现这一点。我认为它类似于地图,但有状态的概念。

换句话说,我想将字符串列表转换为 win 表单单选按钮列表,但对于每个新按钮,我想在前一个 y 坐标上添加 20。比如:

new RadioButton(Text=str,Location=new Point(20,y+20),Width=350)

【问题讨论】:

    标签: f#


    【解决方案1】:

    你可以使用List.fold:

    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
    

    【讨论】:

    • 不错。对于像我这样的新手(语法仍然令人困惑),一开始会弯曲,但我明白了。
    • @Lee 谢谢,这对我帮助很大,但仅供参考,List.fold 示例当前无法编译(即使声明了strings 列表)。请问可以修改吗?
    【解决方案2】:

    您可以通过引用来访问和更改变量

    let x = ref 0
    x := !x + 5
    new Point(20,!x+20)
    

    你可以在闭包中使用这样的变量。

    你也可以使用mapi : http://msdn.microsoft.com/en-us/library/ee353425.aspx

    并根据inew Point(20,i*20+20) 为y 增加价值

    【讨论】:

    • 啊,我没有看到mapi,谢谢。关于 ref 方法,这仍然不是一种常见的“功能”方法,对吗?我在努力强迫自己在学习过程中避免旧习惯。
    • 正确。但我个人还是喜欢我的旧习惯。
    【解决方案3】:

    使用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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 2010-12-19
      • 1970-01-01
      • 2012-11-19
      • 1970-01-01
      • 2021-10-28
      • 2017-10-02
      相关资源
      最近更新 更多