Created
May 30, 2017 08:08
-
-
Save dmitryshliugaev/545741d4032b12c890ea59dedb63e44a to your computer and use it in GitHub Desktop.
Conversion function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Исходные данные: | |
Коллекция с уникальными элементами (содержат id). | |
Элементы иммутабельны. | |
Функция преобразования: | |
Принимает новую коллекцию и делает замещение с дельтой. | |
Дельта состоит из операций: добавления, замещения, удаления. | |
Хранит последнюю дельту. | |
Нотифицирует делегат с данными дельты. | |
Функция восстановления: | |
Принимает последнюю дельту и восстанавливает исходную коллекцию. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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