如何通过F#中的键将两个地图相交?

时间:2015-01-21 17:30:17

标签: dictionary f# functional-programming intersect

我想将具有公共密钥的两个F#地图集成到一个Map中,该Map具有公共密钥和两个值的元组作为其值。

即签名就像:

Map<K, T1> -> Map<K, T2> -> Map<K, T1 * T2>

任何简单实用的想法&amp;高效的方式吗?

我知道我可以将各组键交叉,然后构建一个新的地图,我只想做一些不那么脏的事情......

3 个答案:

答案 0 :(得分:7)

之前我遇到过类似的问题,最后解决了这个问题:

let intersect a b = Map (seq {
    for KeyValue(k, va) in a do
        match Map.tryFind k b with
        | Some vb -> yield k, (va, vb)
        | None    -> () })

答案 1 :(得分:2)

一种方法是根据Map.fold

实现这一点
module Map =
    let intersect (m1:Map<'K, 'V1>) (m2:Map<'K, 'V2>) =
        (Map.empty, m1) ||> Map.fold (fun acc k v1 ->
            (acc, Map.tryFind k m2) ||> Option.fold (fun acc v2 ->
                acc |> Map.add k (v1, v2)))

答案 2 :(得分:1)

我过早地发布了这个并将其删除了,因为我不确定这是否只是与键相交...但我想它取消删除它会有什么不妥,因为它是公平的短:

let intersect otherMap =
    Map.filter (fun k _ -> Map.containsKey k otherMap)
    >> Map.map (fun k v1 -> v1, otherMap.[k])

编辑没有中间地图,通过序列:

let intersect otherMap =
    Map.toSeq >> Seq.choose (fun (k, v) ->
        Map.tryFind k otherMap |> Option.map (fun v2 -> v, v2))
    >> Map.ofSeq