Skip to content

Instantly share code, notes, and snippets.

@pirrmann
Created March 21, 2018 14:27
Show Gist options
  • Save pirrmann/6fc518708c6cfb388b3c81280d5ab9a2 to your computer and use it in GitHub Desktop.
Save pirrmann/6fc518708c6cfb388b3c81280d5ab9a2 to your computer and use it in GitHub Desktop.
Differ
type DifferenceType<'TKey, 'T> =
| Added of 'TKey * 'T
| Removed of 'TKey * 'T
| Modified of 'TKey * 'T * 'T * seq<string * (string * string)> with
member this.Key =
match this with
| Added (key, _)
| Removed (key, _)
| Modified (key, _, _, _) -> key
type Differences<'TKey, 'T> =
{
Added: ('TKey * 'T) seq
Removed: ('TKey * 'T) seq
Modified: ('TKey * 'T * 'T * seq<string * (string * string)>) seq } with
member this.AsSingleSeq() = seq {
yield! this.Added |> Seq.map Added
yield! this.Removed |> Seq.map Removed
yield! this.Modified |> Seq.map Modified
}
let getStringMapDifferences<'TKey when 'TKey:comparison> (lineBefore:Map<'TKey, string>) (lineAfter: Map<'TKey, string>) =
lineBefore
|> Map.toSeq
|> Seq.map (fun (key, vBefore) -> let vAfter = lineAfter.[key] in key, (vBefore, vAfter))
|> Seq.filter (fun (_, (vBefore, vAfter)) -> vBefore <> vAfter)
let formatDifferenceChanges changes =
changes
|> Seq.map (fun (propertyName, (oldValue, newValue)) -> sprintf "%s: %s => %s" propertyName oldValue newValue)
|> String.concat System.Environment.NewLine
let getDifferences keyValueMapper itemsDiffGetter itemsBefore itemsAfter =
let setBefore = itemsBefore |> Set.ofSeq
let setAfter = itemsAfter |> Set.ofSeq
let itemsFoundBeforeNotFoundAfter = setBefore - setAfter
let itemsFoundAfterNotFoundBefore = setAfter - setBefore
let dicBefore = itemsFoundBeforeNotFoundAfter |> Seq.map keyValueMapper |> Map.ofSeq
let dicAfter = itemsFoundAfterNotFoundBefore |> Seq.map keyValueMapper |> Map.ofSeq
let keysBefore = dicBefore |> Map.toSeq |> Seq.map fst |> Set.ofSeq
let keysAfter = dicAfter |> Map.toSeq |> Seq.map fst |> Set.ofSeq
let removedKeys = keysBefore - keysAfter
let addedKeys = keysAfter - keysBefore
let modifiedItemsKeys = Set.intersect keysAfter keysBefore
{
Added =
seq {
for key in addedKeys do
let addedItem = Map.find key dicAfter
yield key, addedItem
}
Removed =
seq {
for key in removedKeys do
let removedItem = Map.find key dicBefore
yield key, removedItem
}
Modified =
seq {
for key in modifiedItemsKeys do
let itemBefore = Map.find key dicBefore
let itemAfter = Map.find key dicAfter
yield key, itemBefore, itemAfter, itemsDiffGetter itemBefore itemAfter
}
}
@giuliohome
Copy link

Thank you very much for your gist! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment