我需要将建筑物的门映射到一张地图中,之后我需要使用这些数据填充三个采摘者。
每扇门都包含以下数据:建筑物,水平,范围,门号和其他不太相关的信息。所以我创建了以下地图:
public var doorsMap: [String : [String : [String : [String: Door]]]] = [:]
并且有一个我需要填充此地图的门列表,问题是我无法理解执行此任务的正确语法是什么,我尝试过:
doorsMap[door.building]?[door.level]?[door.range]?[door.number] = door
但这并没有创建内部词典集。当我试图做的时候:
doorsMap[door.building]![door.level]![door.range]![door.number] = door
显然,我得到了:
致命错误:在解包可选值时意外发现nil
因为我试图打开一个零值。
那么swift中的正确语法是从门列表中填充这个地图会是什么?
答案 0 :(得分:1)
单个作业不会创建多个中间目录。你需要明确地做到这一点。
您可以使用以下内容:
func add(door: Door) {
var building = self.doorsMap[door.building] ?? [String : [String:[String: Door]]]()
var level = building[door.level] ?? [String : [String: Door]]()
var range = level[door.range] ?? [String:Door]
range[door.number] = door
level[door.range] = range
building[door.level] = level
self.doorsMap[door.building] = building
}
就个人而言,我会寻找更好的数据结构,也许使用结构来保存doorsMap
。该结构可以具有处理门的插入和检索的功能。
也许是这样的:
struct Door {
let building: String
let level: String
let range: String
let number: String
}
struct DoorMap {
private var buildingsSet = Set<String>()
private var levelsSet = Set<String>()
private var rangesSet = Set<String>()
private var numberSet = Set<String>()
private var doorsArray = [Door]()
var buildings: [String] {
get {
return Array(buildingsSet).sorted()
}
}
var levels: [String] {
get {
return Array(levelsSet).sorted()
}
}
var ranges: [String] {
get {
return Array(rangesSet).sorted()
}
}
var numbers: [String] {
get {
return Array(numberSet).sorted()
}
}
var doors: [Door] {
get {
return doorsArray
}
}
mutating func add(door: Door) {
buildingsSet.insert(door.building)
levelsSet.insert(door.level)
rangesSet.insert(door.range)
numberSet.insert(door.number)
doorsArray.append(door)
}
func doorsMatching(building: String? = nil, level: String? = nil, range: String? = nil, number: String? = nil) -> [Door]{
let matches = doorsArray.filter { (potentialDoor) -> Bool in
var included = true
if let b = building {
if potentialDoor.building != b {
included = false
}
}
if let l = level {
if potentialDoor.level != l {
included = false
}
}
if let r = range {
if potentialDoor.range != r {
included = false
}
}
if let n = number {
if potentialDoor.number != n {
included = false
}
}
return included
}
return matches
}
}
var map = DoorMap()
let d1 = Door(building: "b1", level: "1", range: "r1", number: "1")
let d2 = Door(building: "b1", level: "2", range: "r1", number: "2")
let d3 = Door(building: "b2", level: "2", range: "r1", number: "2")
map.add(door: d1)
map.add(door: d2)
map.add(door: d3)
let b1Doors = map.doorsMatching(building:"b1")
let level2Doors = map.doorsMatching(level:"2")
let allBuildings = map.buildings()
现在,也许您有关于建筑物和楼层等的更多信息,因此它们也可以是结构而不仅仅是字符串。