Skip to content

Instantly share code, notes, and snippets.

@dmitryshliugaev
Created May 30, 2017 08:08
Show Gist options
  • Save dmitryshliugaev/545741d4032b12c890ea59dedb63e44a to your computer and use it in GitHub Desktop.
Save dmitryshliugaev/545741d4032b12c890ea59dedb63e44a to your computer and use it in GitHub Desktop.
Conversion function
Исходные данные:
Коллекция с уникальными элементами (содержат id).
Элементы иммутабельны.
Функция преобразования:
Принимает новую коллекцию и делает замещение с дельтой.
Дельта состоит из операций: добавления, замещения, удаления.
Хранит последнюю дельту.
Нотифицирует делегат с данными дельты.
Функция восстановления:
Принимает последнюю дельту и восстанавливает исходную коллекцию.
import UIKit
protocol CollectionDelegate {
func onCollectionChanged(diff:[[String: Any]])
func onDiffApply(dict:[String: Any])
}
enum OperationType {
case removed
case replaced
case added
}
class MyCollection: NSObject {
private var dict: [String: Any] = [:]
private var lastDiff: [[String: Any]] = []
public var delegate: CollectionDelegate?
open func replace(newDict: [String: Any]) -> Void {
lastDiff = []
dict.forEach { (key: String, value: Any) in
if newDict[key] == nil {
lastDiff.append(["newValue": [key:value], "operation": OperationType.removed])
}
}
newDict.forEach { (key: String, value: Any) in
if let elem = dict[key] {
lastDiff.append(["newValue": [key:value], "operation": OperationType.replaced, "oldValue": elem])
} else {
lastDiff.append(["newValue": [key:value], "operation": OperationType.added])
}
}
dict = newDict
if delegate != nil {
delegate?.onCollectionChanged(diff: lastDiff)
}
}
open func applyDiff(diff: [[String:Any]]) {
for elem in diff {
if let operation: OperationType = elem["operation"] as? OperationType,
let newValue:[String: Any] = elem["newValue"] as? [String: Any] {
switch operation {
case .added:
if let key = newValue.keys.first {
dict.removeValue(forKey: key)
}
case .replaced:
if let oldValue:[String: Any] = elem["oldValue"] as? [String: Any],
let key = oldValue.keys.first {
dict[key] = oldValue.values.first
}
case .removed:
if let key = newValue.keys.first {
dict[key] = newValue.values.first
}
}
}
}
if delegate != nil {
delegate?.onDiffApply(dict: dict)
}
}
open func applyLast() {
if !lastDiff.isEmpty {
applyDiff(diff: lastDiff)
lastDiff = []
}
}
}
class DelegateCollect: NSObject, CollectionDelegate {
func onCollectionChanged(diff: [[String: Any]]) {
print("\(diff)\n")
}
func onDiffApply(dict: [String : Any]) {
print("\(dict)\n")
}
}
var collect: MyCollection = MyCollection()
var delegate: DelegateCollect = DelegateCollect()
collect.delegate = delegate
collect.replace(newDict: ["1":1, "2":2 ,"3":3])
collect.replace(newDict: ["2":2, "3":3 ,"4":4])
collect.applyLast()
collect.applyLast()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment