在 F# 中,如何合并 2 个 Collections.Map 实例?

发布于 2024-09-27 21:16:34 字数 43 浏览 6 评论 0原文

我正在尝试合并两个地图,但没有用于加入集合的内置方法。那么你该怎么做呢?

I am trying to merge two Maps, but there is no built in method for joining Collections. So how do you do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

囚我心虐我身 2024-10-04 21:16:34

您可以使用 Map.fold 和 Map.add 来实现此操作,因为 add 实际上是添加/替换:

let map1 = Map.ofList [ 1, "one"; 2, "two"; 3, "three" ]
let map2 = Map.ofList [ 2, "two"; 3, "oranges"; 4, "four" ]


let newMap = Map.fold (fun acc key value -> Map.add key value acc) map1 map2

printfn "%A" newMap 

未提供开箱即用的合并功能的原因可能是您需要处理键冲突。在这个简单的合并算法中,我们简单地从第二个映射中获取键值对,这可能不是您想要的行为。

You can implement this using Map.fold and Map.add, since add is actually add/replace:

let map1 = Map.ofList [ 1, "one"; 2, "two"; 3, "three" ]
let map2 = Map.ofList [ 2, "two"; 3, "oranges"; 4, "four" ]


let newMap = Map.fold (fun acc key value -> Map.add key value acc) map1 map2

printfn "%A" newMap 

Probably the reason merge isn't provided out of the box is that you need to deal with key conflicts. In this simple merge algorithm we simple take the key value pair from the second map, this may not be the behaviour you want.

上课铃就是安魂曲 2024-10-04 21:16:34

另一种方法是:

let merge (a : Map<'a, 'b>) (b : Map<'a, 'b>) (f : 'a -> 'b * 'b -> 'b) =
    Map.fold (fun s k v ->
        match Map.tryFind k s with
        | Some v' -> Map.add k (f k (v, v')) s
        | None -> Map.add k v s) a b

如果存在重复键,它可以让您决定想要什么值。

示例:

let a = Map([1,11;2,21;3,31;])

let b = Map([3,32; 4,41;5,51;6,61;])

merge a b (fun k (v, v') -> v + v');;

//Result
val it : Map<int,int> =
  map [(1, 11); (2, 21); (3, 63); (4, 41); (5, 51); (6, 61)]

请注意键 3 是不同的。

An alternative way is this:

let merge (a : Map<'a, 'b>) (b : Map<'a, 'b>) (f : 'a -> 'b * 'b -> 'b) =
    Map.fold (fun s k v ->
        match Map.tryFind k s with
        | Some v' -> Map.add k (f k (v, v')) s
        | None -> Map.add k v s) a b

It lets you decide on what value you want if there is duplicate keys.

Example:

let a = Map([1,11;2,21;3,31;])

let b = Map([3,32; 4,41;5,51;6,61;])

merge a b (fun k (v, v') -> v + v');;

//Result
val it : Map<int,int> =
  map [(1, 11); (2, 21); (3, 63); (4, 41); (5, 51); (6, 61)]

Notice that the key 3 is different.

一口甜 2024-10-04 21:16:34

定义以下函数:

let join (p:Map<'a,'b>) (q:Map<'a,'b>) = 
    Map(Seq.concat [ (Map.toSeq p) ; (Map.toSeq q) ])

示例:

let a = Map([1,11;2,21;3,31;])

let b = Map([3,32; 4,41;5,51;6,61;])

let c = join a b

和结果:

val c : Map<int,int> =
  map [(1, 11); (2, 21); (3, 32); (4, 41); (5, 51); (6, 61)]

Define the following function:

let join (p:Map<'a,'b>) (q:Map<'a,'b>) = 
    Map(Seq.concat [ (Map.toSeq p) ; (Map.toSeq q) ])

example:

let a = Map([1,11;2,21;3,31;])

let b = Map([3,32; 4,41;5,51;6,61;])

let c = join a b

and the result:

val c : Map<int,int> =
  map [(1, 11); (2, 21); (3, 32); (4, 41); (5, 51); (6, 61)]
苦妄 2024-10-04 21:16:34

如果您更喜欢使用函数组合,您可以定义一个 join 函数,如下所示:

let join (m1:Map<'a,'b>) (m2:Map<'a,'b>) = 
    Map.foldBack Map.add m2 m1

鉴于 m1m2 是 Map,您可以像这样使用它:

m3 = join m1 m2

一些警告:

  • m2中的键将覆盖m1中的键
  • 正如其他人指出的那样,让较小的地图作为第二个参数会更快,因为这会导致更少的插入

If you prefer using function composition you could define a join function like this:

let join (m1:Map<'a,'b>) (m2:Map<'a,'b>) = 
    Map.foldBack Map.add m2 m1

Given that m1 and m2 are Maps you would then use it like this:

m3 = join m1 m2

Some caveats:

  • Keys in m2 will overwrite those in m1
  • As others have noted it's faster to let the smaller map be the second argument as it will result in fewer insertions
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文