0

在阅读 Robert C. Martin 的《清洁代码》一书时,他说您应该始终尝试保持 1 到 2 级缩进。最多三个。

假设我们有一个类型为[Int:[Int:[Int:String]]](swift) 的字典 (myDict),并且我们想要遍历所有值,我们将使用一段代码:

for (key1, value1) in myDict
{
    for (key2, value2) in value1
    {
         for (key3, value3) in value2
         {
              //Do stuff
         }
    }
}

如您所见,'//Do stuff' 部分的意图是 4 次,而不是 <=3。

我如何能够在保持最多 3 级缩进(最好是 1 或 2)的同时制作此代码?

这可能吗?我希望答案适用于所有语言,但是,如果它不是正确的,它可能适用于 Swift 吗?

4

2 回答 2

1

首先要意识到,如果您的所有数据都仅在最深的字典中,那么嵌套字典与平面字典相比没有优势。因此,让我们将索引合并到一个对象中:

struct MyIndex : Hashable {
    let indices: (Int, Int, Int)

    init(_ index1: Int, _ index2: Int, _ index3: Int) {
        self.indices = (index1, index2, index3)
    }

    var hashValue: Int {
        return indices.2 // this should ideally use all the 3 indices
    }

    public static func ==(lhs: MyIndex, rhs: MyIndex) -> Bool {
        return lhs.indices == rhs.indices
    }
}

(顺便说一句,这正是IndexPathUIKit 正在做的事情)。

然后我们可以只使用我们的索引:

var dictionary: [MyIndex: String] = [:]

dictionary[MyIndex(0, 0, 0)] = "test"
dictionary[MyIndex(0, 1, 2)] = "test2"

for (index, value) in dictionary {
    print(index.indices, value)
}

我一次迭代所有值,而不是 3 个嵌套循环。

于 2017-01-15T10:49:22.637 回答
0

通用点头不是很优雅的方式是创建函数......

func iterateFirstDict(dictionary: [Int: [Int: [Int: String]]]) {
    for (key, value) in dictionary {
        iterateSecondDictionary(value)
    }
}

func iterateSecondDictionary(dictionary: [Int: [Int: String]]) {
    for (key, value) in dictionary {
        iterateThirdDictionary(value)
    }
}

func iterateThirdDictionary(dictionary: [Int: String]) {
    for (key, value) in dictionary {
        // do stuff
    }
}

显然,您会使用更具描述性的函数名称,但因为我们无法看到您的数据是什么,所以我无法在此处添加这些数据。

解决此问题的更好方法是在其中嵌入数据对象和函数来为您完成工作。

于 2017-01-15T10:36:12.943 回答