в F #, Как вы сливаете 2 экземпляра Collections.Map - PullRequest
14 голосов
/ 20 октября 2010

Я пытаюсь объединить две Карты, но нет встроенного метода для присоединения к Коллекциям.Так как ты это делаешь?

Ответы [ 3 ]

25 голосов
/ 20 октября 2010

Вы можете реализовать это, используя 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 

Вероятно, причина слияния не предоставляется из коробки, это то, что вам нужноиметь дело с ключевыми конфликтами.В этом простом алгоритме слияния мы просто берем пару ключ-значение из второй карты, это может быть не тем поведением, которое вам нужно.

11 голосов
/ 19 февраля 2012

Альтернативный способ заключается в следующем:

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 отличается.

8 голосов
/ 20 октября 2010

Определите следующую функцию:

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)]
...