Skip to content

Instantly share code, notes, and snippets.

@porfirion
Created May 15, 2019 16:56
Show Gist options
  • Save porfirion/988c13a6c00428329dcccfcc51ac9f7a to your computer and use it in GitHub Desktop.
Save porfirion/988c13a6c00428329dcccfcc51ac9f7a to your computer and use it in GitHub Desktop.
// holds list of already existing entities ('a list)
// Allows to check if new entities already exist in list.
// if entity already exists - add it's id into idsList
// if entity doesn't exists - add to existing, add to list of notExistedEntities, add it's id into idsList
type EntityHolder(initialEntities: 'a seq, idGetter: 'a -> string, entityComparator: 'a -> 'a -> bool) =
let mutable existingEntities : 'a list = initialEntities |> Seq.toList
member this.Add (entities: 'a seq) : 'a list * string list =
let notExistedEntities, ids =
entities
|> Seq.fold
(
fun (entitiesToSave: 'a list, idsList: string list) currentEntity ->
match List.tryFind (entityComparator currentEntity) existingEntities with
| Some alreadyExitingEntity ->
let id = idGetter alreadyExitingEntity
(entitiesToSave, (id :: idsList))
| None ->
existingEntities <- currentEntity :: existingEntities
let id = idGetter currentEntity
(currentEntity :: entitiesToSave, id :: idsList)
)
([], [])
notExistedEntities, ids
type EntityHolderMap(initialEntities: 'a seq, idGetter: 'a -> string, hashGetter: 'a -> string) =
let mutable existingEntities : Map<string, 'a> = initialEntities |> Seq.map (fun entity -> (hashGetter entity), entity) |> Map.ofSeq
member this.Add (entities: 'a seq) : 'a list * string list =
let notExistedEntities, ids =
entities
|> Seq.fold
(
fun (entitiesToSave: 'a list, idsList: string list) currentEntity ->
let currentHash = hashGetter currentEntity
match existingEntities.TryFind currentHash with
| Some alreadyExitingEntity ->
let id = idGetter alreadyExitingEntity
(entitiesToSave, (id :: idsList))
| None ->
existingEntities <- existingEntities.Add (currentHash, currentEntity)
let id = idGetter currentEntity
(currentEntity :: entitiesToSave, id :: idsList)
)
([], [])
notExistedEntities, ids
let AddEntities
(idGetter: 'a -> string)
(entityComparator: 'a -> 'a -> bool)
(initialEntities: 'a list)
(addingEntities: 'a list) : 'a list * 'a list * string list =
addingEntities
|> Seq.fold
(
fun (existingEntities: 'a list, entitiesToSave: 'a list , idsList: string list) currentEntity ->
match List.tryFind (entityComparator currentEntity) existingEntities with
| Some alreadyExitingEntity ->
let id = idGetter alreadyExitingEntity
(existingEntities, entitiesToSave, (id :: idsList))
| None ->
let id = idGetter currentEntity
(currentEntity :: existingEntities, currentEntity :: entitiesToSave, id :: idsList)
)
(initialEntities, [], [])
let AddEntitiesMap
(idGetter: 'a -> string)
(hashGetter: 'a -> string)
(initialEntities: Map<string, 'a>)
(addingEntities: 'a list) : Map<string, 'a> * 'a list * string list =
addingEntities
|> Seq.fold
(
fun (existingEntities: Map<string, 'a>, entitiesToSave: 'a list , idsList: string list) currentEntity ->
let currentHash = hashGetter currentEntity
match existingEntities.TryFind currentHash with
| Some alreadyExitingEntity ->
let id = idGetter alreadyExitingEntity
(existingEntities, entitiesToSave, (id :: idsList))
| None ->
let id = idGetter currentEntity
(existingEntities.Add (currentHash, currentEntity), currentEntity :: entitiesToSave, id :: idsList)
)
(initialEntities, [], [])
// Example
let AddInts = AddEntities (fun i -> i.ToString()) (fun (i: int) (j: int) -> i = j)
val existingInts : int list = [1; 2; 3]
let existingInts, adding, ids = AddInts existingInts [5; 10]
// Output
val ids : string list = ["10"; "5"]
val existingInts : int list = [10; 5; 1; 2; 3]
val adding : int list = [10; 5]
// Example
let AddIntsMap = AddEntitiesMap (fun i -> i.ToString()) (fun (i: int) -> i.ToString())
let existingIntsMap = Map.ofList [("1", 1); ("2", 2); ("3", 3)]
let existingIntsMap, adding, ids = AddIntsMap existingIntsMap [8; 13]
// Output
val ids : string list = ["13"; "8"]
val existingIntsMap : Map<string,int> = map [("1", 1); ("13", 13); ("2", 2); ("3", 3); ("8", 8)]
val adding : int list = [13; 8]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment