Dictionary Seq.groupBy:保留原始顺序
Dictionary Seq.groupBy:保留原始顺序,dictionary,f#,enumeration,Dictionary,F#,Enumeration,Dictionary–和扩展名为Seq.groupBy–似乎按插入顺序枚举元素,但顺序尚未正式定义(请参阅) 下面是一些代码来演示: 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 <>
Dictionary
–和扩展名为Seq.groupBy
–似乎按插入顺序枚举元素,但顺序尚未正式定义(请参阅)
下面是一些代码来演示:
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
如果要确保序列按每个键的第一次出现排序,则有一种方法:
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])
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)
我是哑巴还是这个问题有点让人困惑?如果你需要保证,我想你要么自己实现,要么使用(一些)
Seq.order
calls@ChaosPandion:我不确定。:-)@卡斯滕克尼:是的,很好。这是显而易见的方法。我在这里寻找创造力。我知道它不是内置的…这就是问题的动力。在一般情况下,如果键与源序列中的元素(不一定)相同,并且键可能会重复,那么保持原始顺序意味着什么?你是担心小组本身的顺序,小组内部的顺序,还是两者都担心?啊!15秒后,使用完全相同的代码(不仅在语义上相同,而且在字面上也相同!),文档不能保证这一点,但我们知道Seq.groupBy
保留每个组中的值顺序,因此您的第一个函数应该做到这一点。我为我的问题添加了另一个可能的解决方案。它的性能与您的类似。你知道它和你的有什么实际的区别吗?函数组合真的让我头疼:)我花了5分钟才弄明白snd>>Seq.map fst>>Seq.min试图实现什么。