Skip to content

Instantly share code, notes, and snippets.

@orient-man
Last active November 3, 2016 08:41
Show Gist options
  • Save orient-man/977e8653819721b233df2f35f7350df7 to your computer and use it in GitHub Desktop.
Save orient-man/977e8653819721b233df2f35f7350df7 to your computer and use it in GitHub Desktop.
let inline mergeWithDiff map1 map2 =
let keys map = map |> Map.toSeq |> Seq.map fst
let inline zeroIfNotFound key map =
map |> Map.tryFind key |> defaultArg <| LanguagePrimitives.GenericZero
Seq.append (map1 |> keys) (map2 |> keys)
|> Seq.distinct
|> Seq.map (fun key ->
let v1 = map1 |> zeroIfNotFound key
let v2 = map2 |> zeroIfNotFound key
key, (v1, v1 - v2))
let inline mergeWithDiff' map1 map2 =
let zero = LanguagePrimitives.GenericZero
let seq1 = map1 |> Map.toSeq |> Seq.map (fun (k, v) -> k, (v, v))
let seq2 = map2 |> Map.toSeq |> Seq.map (fun (k, v) -> k, (zero, -v))
let sum = Seq.fold (fun (sum1, sum2) (v1, v2) -> sum1 + v1, sum2 + v2) (zero, zero)
Seq.append seq1 seq2
|> Seq.groupBy fst
|> Seq.map (fun (k, values) -> k, values |> Seq.map snd |> sum)
let map1 = [("A", 5); ("B", 2); ("C", 7)] |> Map.ofList
let map2 = [("B", 2); ("C", 5); ("D", 3)] |> Map.ofList
mergeWithDiff map1 map2
mergeWithDiff' map1 map2
// seq [("A", (5, 5)); ("B", (2, 0)); ("C", (7, 2)); ("D", (0, -3))]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment