许多涉及字典条目突变的答案往往集中在remove值 -> 改变值 -> 替换值习语,但请注意,删除不是必需的。您同样可以使用例如执行就地突变可选链接
dict["Furniture"]?.removeAtIndex(1)
print(dict)
/* ["Furniture": ["Table", "Bed"],
"Food": ["Pancakes"]] */
但请注意,使用.removeAtIndex(...)
解决方案并不完全安全,除非您执行数组边界检查,确保我们尝试删除元素的索引确实存在。
作为安全的就地突变替代方案,请使用where
可选绑定语句的子句,用于检查我们要删除的索引是否超出范围
let removeElementAtIndex = 1
if let idxs = dict["Furniture"]?.indices where removeElementAtIndex < idxs.endIndex {
dict["Furniture"]?.removeAtIndex(removeElementAtIndex)
}
另一种安全的选择是利用advancedBy(_:limit)
获得一个安全的索引来使用removeAtIndex(...)
.
let removeElementAtIndex = 1
if let idxs = dict["Furniture"]?.indices {
dict["Furniture"]?.removeAtIndex(
idxs.startIndex.advancedBy(removeElementAtIndex, limit: idxs.endIndex))
}
最后,如果使用删除/变异/替换习语,另一个安全的选择是使用flatMap
对于变异步骤,删除给定索引的元素(如果该索引存在于数组中)。例如,对于通用方法(和where
滥用条款:)
func removeSubArrayElementInDict<T: Hashable, U>(inout dict: [T:[U]], forKey: T, atIndex: Int) {
guard let value: [U] = dict[forKey] where
{ () -> Bool in dict[forKey] = value
.enumerate().flatMap{ $0 != atIndex ? $1 : nil }
return true }()
else { print("Invalid key"); return }
}
/* Example usage */
var dict = [String:[String]]()
dict = ["Furniture": ["Table", "Chair", "Bed"], "Food": ["Pancakes"]]
removeSubArrayElementInDict(&dict, forKey: "Furniture", atIndex: 1)
print(dict)
/* ["Furniture": ["Table", "Bed"],
"Food": ["Pancakes"]] */