F#更改列表中的元素并返回完整的新列表

时间:2017-12-17 16:43:17

标签: f#

我有一个(string * (int * int)) list类型的列表。我希望能够搜索列表,通过它找到正确的元素string标识符,对其中一个ints进行计算,然后返回完整的修改后的列表。

示例:

给出一个清单

let st = [("a1",(100,10)); ("a2",(50,20)); ("a3",(25,40))]

我试图创建一个函数来获取其中一个元素并从元组中的ints之一中减去数字。

get ("a2",10) st 
//Expected result: st' = [("a1",(100,10)); ("a2",(40,20)); ("a3",(25,40))]

我觉得我几乎就在那里,但我对以下功能感到困惑:

let rec get (a,k) st =
    match st with
    | (a',(n',p'))::rest when a'=a && k<=n' -> (n'-k,p')::rest
    | (a',(n',p'))::rest                    -> (n',p')::get (a,k) rest
    | _                                     -> failwith "Illegal input"

这将返回[("a2",(40,20)); ("a3",(25,40))],因此缺少第一个a1元素。任何提示?

1 个答案:

答案 0 :(得分:8)

列表是不可变的,因此如果您想“更改一个元素”,您实际上是在创建一个包含一个元素转换的新列表。像这样进行转换的最简单方法是使用List.map函数。我会写一些类似的东西:

let updateElement key f st = 
  st |> List.map (fun (k, v) -> if k = key then k, f v else k, v)

updateElement是一个带有键,更新功能和输入的助手。它返回列表,其中具有给定键的元素已使用给定函数进行转换。例如,要增加与a2关联的第一个数字,您可以写:

let st = [("a1",(100,10)); ("a2",(50,20)); ("a3",(25,40))]

st |> updateElement "a2" (fun (a, b) -> a + 10, b)