4 people like it.
Like the snippet!
List comparison
Find what's been added, removed or changed between two lists (perfom a diff between two lists of items).
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
|
type Change<'a> =
| Added of 'a
| Removed of 'a
| Modified of current : 'a * previous : 'a
let compare (getKey : 'a -> 'b) (hasChanged : 'a -> 'a -> bool) (current : 'a list) (previous : 'a List) : seq<Change<'a>> =
let currentKeys =
current
|> List.map getKey
|> Set.ofList
let previousKeys =
previous
|> List.map getKey
|> Set.ofList
let added =
current |> Seq.filter (fun item ->
let key = item |> getKey
not (previousKeys |> Set.contains key))
let removed =
current |> Seq.filter (fun item ->
let key = item |> getKey
not (currentKeys |> Set.contains key))
let remainingKeys = Set.intersect currentKeys previousKeys
let currentRemaining = current |> List.filter (fun x -> remainingKeys |> Set.contains (x |> getKey))
let previousRemainingLookup =
previous
|> Seq.filter (fun x -> remainingKeys |> Set.contains (x |> getKey))
|> Seq.map (fun x -> getKey x, x)
|> Map.ofSeq
seq {
for key in added do
yield Added key
for key in removed do
yield Removed key
for current in currentRemaining do
let key = getKey current
let previous = previousRemainingLookup.[key]
if hasChanged current previous then yield Modified(current, previous)
}
|
union case Change.Added: 'a -> Change<'a>
union case Change.Removed: 'a -> Change<'a>
union case Change.Modified: current: 'a * previous: 'a -> Change<'a>
val compare : getKey:('a -> 'b) -> hasChanged:('a -> 'a -> bool) -> current:'a list -> previous:List<'a> -> seq<Change<'a>> (requires comparison)
Full name: Script.compare
val getKey : ('a -> 'b) (requires comparison)
val hasChanged : ('a -> 'a -> bool)
type bool = System.Boolean
Full name: Microsoft.FSharp.Core.bool
val current : 'a list
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
val previous : List<'a>
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
type Change<'a> =
| Added of 'a
| Removed of 'a
| Modified of current: 'a * previous: 'a
Full name: Script.Change<_>
val currentKeys : Set<'b> (requires comparison)
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.map
Multiple items
module Set
from Microsoft.FSharp.Collections
--------------------
type Set<'T (requires comparison)> =
interface IComparable
interface IEnumerable
interface IEnumerable<'T>
interface ICollection<'T>
new : elements:seq<'T> -> Set<'T>
member Add : value:'T -> Set<'T>
member Contains : value:'T -> bool
override Equals : obj -> bool
member IsProperSubsetOf : otherSet:Set<'T> -> bool
member IsProperSupersetOf : otherSet:Set<'T> -> bool
...
Full name: Microsoft.FSharp.Collections.Set<_>
--------------------
new : elements:seq<'T> -> Set<'T>
val ofList : elements:'T list -> Set<'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Set.ofList
val previousKeys : Set<'b> (requires comparison)
val added : seq<'a>
module Seq
from Microsoft.FSharp.Collections
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.filter
val item : 'a
val key : 'b (requires comparison)
val not : value:bool -> bool
Full name: Microsoft.FSharp.Core.Operators.not
val contains : element:'T -> set:Set<'T> -> bool (requires comparison)
Full name: Microsoft.FSharp.Collections.Set.contains
val removed : seq<'a>
val remainingKeys : Set<'b> (requires comparison)
val intersect : set1:Set<'T> -> set2:Set<'T> -> Set<'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Set.intersect
val currentRemaining : 'a list
val filter : predicate:('T -> bool) -> list:'T list -> 'T list
Full name: Microsoft.FSharp.Collections.List.filter
val x : 'a
val previousRemainingLookup : Map<'b,'a> (requires comparison)
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
Multiple items
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IEnumerable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
member Add : key:'Key * value:'Value -> Map<'Key,'Value>
member ContainsKey : key:'Key -> bool
override Equals : obj -> bool
member Remove : key:'Key -> Map<'Key,'Value>
...
Full name: Microsoft.FSharp.Collections.Map<_,_>
--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val ofSeq : elements:seq<'Key * 'T> -> Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.ofSeq
val key : 'a
val current : 'a
val previous : 'a
More information