问题
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