我有一本从另一个班级更新的词典。我在字典上有一个属性观察者,所以我知道何时添加或删除了一个值。
我根据字典的值创建一个排序数组。我需要更新此数组并保留与更新相关联的索引以与UITableView一起使用。我的UI是这样的,无法批量重新加载数据 - 我需要根据更新的内容直接插入或删除行。
我把它简化成了一个游乐场:
func dictionaryUpdated() {
print("dictionary updated")
// Add or remove string at index depending on order.
}
var myDictionary : [Int:String] = ["Bob".hashValue:"Bob","Dave".hashValue:"Dave","Yoda".hashValue:"Yoda","Windu".hashValue:"Windu","Obi Wan".hashValue:"Obi Wan","Qui-gon".hashValue:"Qui-gon","Anakin".hashValue:"Anakin"] { didSet { dictionaryUpdated() } }
func addEntry(entry: String) {
myDictionary[entry.hashValue] = entry
}
func removeEntry(entry: String) {
myDictionary.removeValueForKey(entry.hashValue)
}
// sort the keys alphabetically while creating the array
var valuesArray = myDictionary.values.sort { (lhs, rhs) -> Bool in
return lhs < rhs
}
我尝试过使用NSMutableOrderedSet,但键只能是字符串。
答案 0 :(得分:1)
只是在操场上玩耍。虽然可以更加优雅......
var valuesArray: [String] = [] { didSet { valuesArray.sortInPlace { $0 < $1 } } }
func dictionaryUpdated(old: [Int: String]) {
let added = myDictionary.count > old.count
let item: [String] = added ? myDictionary.values.filter { !old.values.contains($0) } : old.values.filter { !myDictionary.values.contains($0) }
valuesArray += item
let index = valuesArray.indexOf(item[0])!
print("item " + (added ? "added" : "removed") + ": \(item) at index \(index)")
}
var myDictionary: [Int: String] = ["Yoda".hashValue: "Yoda", "Windu".hashValue: "Windu", "Obi Wan".hashValue: "Obi Wan"] {
didSet {
dictionaryUpdated(oldValue)
}
}
addEntry("Darth Vader")
print(valuesArray)
输出:
item added: ["Darth Vader"] at index 0
["Darth Vader", "Obi Wan", "Windu", "Yoda"]
答案 1 :(得分:0)
假设在属性更改之前和之后都有排序数组(可以通过另一个实例变量实现),您需要做的是比较旧数组和新数组,并检测哪些索引发生了变化。
这个问题的一个优雅的解决方案是向diff
类添加Array
方法来计算差异。该方法可能如下所示:
extension Array where Element: Equatable {
func diff(other: [Element]) -> (added: [Int], deleted: [Int], moved: [(from: Int, to: Int)]) {
var added: [Int] = []
var deleted: [Int] = []
var moved: [(from: Int, to: Int)] = []
for (i, item) in enumerate() {
if let j = other.indexOf({$0 == item}) {
if i != j {
moved.append((from: i, to: j))
}
} else {
deleted.append(i)
}
}
for (i, item) in other.enumerate() {
if indexOf({$0 == item}) == nil {
added.append(i)
}
}
return (added: added, deleted: deleted, moved: moved)
}
}
然后你会这样使用:valuesArray.diff(oldValuesArray)
。