"Subsetting" a dictionary in F# -
i'm beginner in f# , i'm trying write function subset dictionary given list, , return result.
i tried this, doesn't work.
let subset (dict:dictionary<'t,'u>) (sub_list:list<'t>) = let z = dict.clear sub_list |> list.filter (fun k -> dict.containskey k) |> list.map (fun k -> (k, dict.trygetvalue k) ) |> list.iter (fun s -> z.add s) |> list.iter (fun s -> z.add s);; --------------------------------------^^^ stdin(597,39): error fs0039: field, constructor or member 'add' not defined
perhaps there native function in f# ?
thanks
edit @theinnerlight answer below can educate me bit more, , tell me how should adapt function if want return original variable being modified ? (of course possible go call function, call temp variable, , reassign)
you have written:
let z = dict.clear
z
of type unit->unit
yet calling z.add
.
i suspect want write
let subset (dict:dictionary<'t,'u>) (sub_list:list<'t>) = let z = dictionary<'t,'u>() // create new empty dictionary sub_list |> list.filter (fun k -> dict.containskey k) |> list.map (fun k -> (k, dict.[k]) ) |> list.iter (fun s -> z.add s) z
trygetvalue
going return of type bool*'u
in f#, suspect don't want if filtering containskey
want directly dict.[k]
.
note dictionary
mutable collection if call dict.clear()
, wouldn't return new empty dictionary, mutate existing 1 clearing elements. immutable f# data structure used key-value relationships map
, see https://msdn.microsoft.com/en-us/library/ee353880.aspx things can map
.
here map version (this solution recommend):
let subset map sublist = sublist |> list.choose (fun k -> option.map (fun v -> k,v) (map.tryfind k map)) |> map.oflist
edit (in response question edit modifying input variable):
it's possible update existing dictionary using destructive update operator <-
on mutable variable.
option 1:
let mutable dict = dictionary<key,value>() // replace initial dictionary let lst = [] // list check against dict <- sublist dict lst
likewise, first function changed perform side effect (removing unwanted elements).
option 2:
let subset (d : system.collections.generic.dictionary<'t,'u>) (sub_list : list<'t>) = sub_list |> list.filter (d.containskey >> not) |> list.iter (d.remove >> ignore)
for f# beginner don't recommend option 1 , really don't recommend option 2.
the functional approach favour immutable values, pure functions, etc. means better off thinking of functions defining data transformations rather defining list of instructions performed.
because f# multi-paradigm language, it's easy fall on imperative in stages gain learning new language if force adopt standard paradigm , idioms of language if idioms feel strange , uncomfortable begin with.
the immutable data structures map
, list
pretty efficient @ sharing data providing time complexity these go-to collections when working in f#.
Comments
Post a Comment