我已经想出了我在F#代码中需要的这个简单的算法(将元组列表转换为列表键的映射集合):
let MergeIntoMap<'K,'V when 'K: comparison>(from: seq<'K*'V>): Map<'K,seq<'V>>=
let keys = from.Select(fun (k,v) -> k)
let keyValuePairs = seq {
for key in keys do
let valsForKey = from.Where(fun (k,v) -> key = k).Select(fun (k,v) -> v) |> seq
yield key,valsForKey
}
keyValuePairs |> Map.ofSeq
示例输入:
[ ("a", 1); ("b", 2), ("a", 3) ]
输出:
dict [ ("a", [1; 3]), ("b", [2]) ]
我认为这必须是BCL或F#的高阶函数中的一部分吗?如果是,有人可以引用我吗?因为我确定我的代码效率不高,因为它......
答案 0 :(得分:3)
似乎你想得到类似的东西
let toGroupMap x =
x
|> Seq.groupBy fst
|> Seq.map
(fun (k,v) -> k, v |> Seq.map snd |> Seq.toArray)
|> Map.ofSeq
FSI:
val toGroupMap : x:seq<'a * 'b> -> Map<'a,'b []> when 'a : comparison
val input : (string * int) list = [("a", 1); ("b", 2); ("a", 3)]
val output : Map<string,int []> = map [("a", [|1; 3|]); ("b", [|2|])]
修改强>
在评论中写了Fyodor Soikin,有一种扩展方法ToLookup
,它可能会满足您的需求。
open System.Linq
let output = input.ToLookup(fst, snd)
您可以阅读here关于ILookup和IDictionary接口之间的区别