F# Change element in list and return full new list

岁酱吖の 提交于 2019-12-07 10:20:44

问题


I have a list of type (string * (int * int)) list. I want to be able to search through the list, finding the right element by it's string identifier, do a calculation on one of the ints, and then return the full, modified list.

Example:

Given a list

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

I'm trying to make a function which gets one of the elements and subtracts number from one of the ints in the tuple.

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

I feel I'm almost there, but am a little stuck with the following function:

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"

This returns [("a2",(40,20)); ("a3",(25,40))] and is thus missing the first a1 element. Any hints?


回答1:


Lists are immutable, so if you want to "change one element" you are really creating a new list with one element transformed. The easiest way to do a transformation like this is to use List.map function. I would write something like:

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

updateElement is a helper that takes a key, update function and an input. It returns list where the element with the given key has been transformed using the given function. For example, to increment the first number associated with a2, you can write:

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

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


来源:https://stackoverflow.com/questions/47857249/f-change-element-in-list-and-return-full-new-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!