Reputation: 7635
Given a list of key/value pairs:
do
[("A", 1);("B",2)]
|> (fun list ->
for item in list do
match item with
| ("A", x) -> //expression assigning x to variable "A"
| ("B", x) -> //expression assigning x to variable "B"
| _ -> //default expression
)
Are there some expressions I can write that will accomplish the same thing as
let A = 1
let B = 2
I know in advance that the list has no more than 10 items, and that the items are tuples of <string, int> but don't know in advance whether "A" or "B" or other keys may be present or if the list is be empty.
Basically, decompose the list into a set of typed variables.
UPDATE: Notes on Context
In my app I receive a list of key/value pairs just like this from an upstream program maintained by a different team. I expect certain keys to be in the list, which i want to assign to typed variables for later processing. I'll throw an exception if ones I need are missing. However I don't want to be locked in to any given set of variable names, except for the expected ones. For all of them, I want to be able to assign them at run time.
Upvotes: 3
Views: 773
Reputation: 10624
It sounds like you have some dynamic data that can be represented well as a map:
let data = Map [ ("A", 1); ("B", 2) ]
let a = Map.find "A" data
// throws an exception if "A" is not present
let b = Map.find "B" data
// throws an exception if "B" is not present
let c = Map.tryFind "C" data
// "C" is not present so c = None
Note: In F# the convention is for binding names (variable names) to start with a lower case letter.
Upvotes: 1
Reputation: 243041
If you want to do something with the variables later on in the code, then they will need to be in scope - so you will inevitably have to declare the variables in some way. The easiest option is to make them mutable and mutate them according to the values in the list:
let mutable A = 0
let mutable B = 0
To make the mutation a bit easier, you can create a lookup table with setters:
let setters =
dict [ ("A", fun x -> A <- x); ("B", fun x -> B <- x) ]
This now lets you iterate over the inputs, use dictionary lookup to get the appropriate setter and invoke it to set the variable value:
for var, value in [("A", 1);("B",2)] do
setters.[var] value
With the limited context of your question, it is a bit hard to say whether this is a good way of achieving what actually motivated your question - as F# code, it does look like a bit ugly and it is likely that if you add more context, someone can suggest a better way.
Upvotes: 7