字典词典词典的语法理解

时间:2018-03-17 20:07:09

标签: ios swift dictionary

我需要将建筑物的门映射到一张地图中,之后我需要使用这些数据填充三个采摘者。

每扇门都包含以下数据:建筑物,水平,范围,门号和其他不太相关的信息。所以我创建了以下地图:

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中的正确语法是从门列表中填充这个地图会是什么?

1 个答案:

答案 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()

现在,也许您有关于建筑物和楼层等的更多信息,因此它们也可以是结构而不仅仅是字符串。