【问题标题】:F# Add element created in a for loop to a listF#将在for循环中创建的元素添加到列表中
【发布时间】:2020-02-19 01:58:20
【问题描述】:

我想向列表中添加一个元素。元素将在 for 循环内创建。我目前拥有的是

let MaxCubeVolume tpList = 
    let list1 = [] 
    printfn "%A" list1 
    for l,w,h in tpList do
        let vol = CubeVolume l w h 
        let list = vol::list1
        printfn "%A" list 

其中 list1 是我要添加到的主列表,而 list 是我要用来添加到该列表的内容。 CubeVolume 正在工作,它需要 3 个浮点数并返回立方体的体积。 tpList 是一个包含 3 个浮点数的元组列表。我迷路的地方是如何将 vol 添加到主列表中?

【问题讨论】:

    标签: list f# tuples


    【解决方案1】:

    F# 列表是不可变的。你不能“改变”它们。您不会向它们“添加”元素。您只能从旧列表中创建一个列表(但旧列表保持不变并且仍然可以使用)。

    但这是函数式编程的错误思维框架。在函数式编程中,您不会通过重复修改数据结构来计算结果。相反,您可以将较小的数据结构组合成较大的数据结构,或者使用(和组合)为您完成这些工作的原始函数。

    特别是,如果您有一个假设的三元组列表,并且您有一个函数可以将一个这样的三元组转换为假设的一个数字,并且您想让自己成为一个列表这些数字 - 这是一个众所周知的原始操作,称为 map

    let tripleToNumber (l, w, h) = CubeVolume l w h
    let list1 = List.map tripleToNumber tpList
    

    或者你可以指定内联的转换函数,而不用给它一个单独的名字:

    let list1 = List.map (fun (l, w, h) -> CubeVolume l w h) tpList
    

    然后你可以使用|>操作符重新排列List.map的参数,让它看起来更好看一点:

    let list1 = tpList |> List.map (fun (l, w, h) -> CubeVolume l w h)
    

    或者,您也可以使用 F# 列表推导,它们是语法糖:它们在底层做同样的事情,但(可以说)看起来更好:

    let list1 = [for (l, w, h) in tpList -> CubeVolume l w h]
    

    这里要注意的重要一点是,上述 sn-ps 实际上都没有更改任何数据。它们都通过转换旧数据来生成新数据。

    【讨论】:

    • 喜欢这是一个语言基础问题的全面性。
    • 非常感谢!
    【解决方案2】:

    除了 Fyodor 的答案(非常全面)之外,对于您为函数命名的通用 F# 解决方案(查找序列计算结果的最大值)将是编写 mapmax 函数。这些函数存在于标准 F# 集合模块(SeqListArray)上,您可以使用 |> 运算符将它们链接在一起:

    let maxCubeVolume tpList = 
        tpList |> Seq.map (fun (l,w,h) -> CubeVolume l w h) |> Seq.max
    

    您也可以使用 >> 运算符将它们组合在一起:

    List.map (fun (l,w,h) -> CubeVolume l w h) >> List.max
    

    标准 F# 集合上还有一个内置函数 maxBy,它返回集合中对于给定函数具有最大值的元素。这将返回立方体本身(体积最大的那个),而不是体积的计算值。下面是一个使用Seq(F# 集合类型中最通用的类​​型)的示例:

    let maxCubeVolume tpList = 
        tpList |> Seq.maxBy (fun (l,w,h) -> CubeVolume l w h)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-28
      • 2015-01-25
      • 2016-08-25
      • 2020-08-12
      • 2017-09-22
      • 2019-11-05
      • 1970-01-01
      • 2019-04-02
      相关资源
      最近更新 更多