Søren Debois
Søren Debois

Reputation: 5688

Hashtable in F#

Is there an alternative to System.Collections.Generic.Dictionary or System.Collections.Hashtable?

I'm unhappy with the former because it returns value using byref, i.e., I need to do the annoying

let x = ref ""
if hashtable.TryGetValue (key, x) then
    // Found, value in !x
else
    // Not found. 

I'm unhappy with the latter because it's not generic.

EDIT. I'd prefer something generic syntactically looking like Map.tryFind, i.e.,

match Hashtable.tryFind k hashtable with
| None -> ...    // Not found
| Some v -> ...  // Found v. 

Upvotes: 7

Views: 6070

Answers (2)

Daniel
Daniel

Reputation: 47904

Out parameters are part of living with the .NET framework. F# does minimize the pain, however, by automatically tuplizing them along with the return value. So, using Dictionary<_,_> you can do:

match d.TryGetValue(key) with
| true, x -> ... //tuple of return value and out parameter
| _ -> ...

See Passing by Reference on MSDN.

You could easily wrap that into an extension:

type System.Collections.Generic.Dictionary<'K, 'V> with
  member x.TryFind(key) =
    match x.TryGetValue(key) with
    | true, v -> Some v
    | _ -> None

Upvotes: 19

MarcinJuraszek
MarcinJuraszek

Reputation: 125620

There are two collection types in F# you should look at:

Collections.Set<'T> Class (F#)

Immutable sets based on binary trees, where comparison is the F# structural comparison function, potentially using implementations of the IComparable interface on key values.

Collections.Map<'Key,'Value> Class (F#)

Immutable maps. Keys are ordered by F# generic comparison.

Map has a function you're looking for:

Map.TryFind

Lookup an element in the map, returning a Some value if the element is in the domain of the map and None if not.

Upvotes: 6

Related Questions