Dictionary<_,_>
- 和Seq.groupBy
扩展名 - 似乎按插入顺序枚举元素,但订单正式未定义(请参阅this question)。
这里有一些代码可以证明:
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
我需要一个保证这种行为的分组功能。什么是最好的(consice,有效,惯用,......)方式呢?
修改
这是一种方法:
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])
答案 0 :(得分:2)
如果你想确保序列按每个键的第一次出现排序,那么这是一种方法:
let groupByOP f s =
s
|> Seq.mapi (fun i x -> i,x)
|> Seq.groupBy (snd >> f)
|> Seq.sortBy (snd >> Seq.map fst >> Seq.min)
|> Seq.map (fun (k,vs) -> k, vs |> Seq.map snd)
如果您还希望按初始位置对每个组进行排序,那么我认为这样的事情应该有效:
let groupByOP f s =
s
|> Seq.mapi (fun i x -> i,x)
|> Seq.groupBy (snd >> f)
|> Seq.map (fun (k,vs) -> k, vs |> Seq.sortBy fst)
|> Seq.sortBy (snd >> Seq.head >> fst)
|> Seq.map (fun (k,vs) -> k, vs |> Seq.map snd)