Dictionary<_,_>
–and Seq.groupBy
by extension–appears to enumerate elements in insertion order, however the order is officially undefined (see this question).
Here's a bit of code to demonstrate:
let groupByPreservesOrder l =
let l2 =
l
|> Seq.groupBy id
|> Seq.map fst
|> Seq.toList
(l = l2)
let l = List.init 1000 (fun i ->
if i % 2 <> 0 then -(i) else i / 2)
groupByPreservesOrder l //true
I need a grouping function that guarantees this behavior. What is the best (consice, efficient, idiomatic, ...) way to go about it?
EDIT
Here's one way to do it:
let groupByStable f items =
let items = items |> Seq.map (fun x -> f x, x) |> Seq.toList
let d = items |> Seq.groupBy fst |> dict
items
|> Seq.distinctBy fst
|> Seq.map (fun (k, _) -> k, Seq.map snd d.[k])