如何保持 1 到 2 行缩进。

How to keep between 1 and 2 lines of indentation.

在阅读 Robert C. Martin 的书 'Clean Code' 时,他说您应该始终尝试保持 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 级)的情况下制作此代码?

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

通用点头不太优雅的方法是创建函数...

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
    }
}

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

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

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

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
    }
}

(顺便说一下,这正是 UIKit 中的 IndexPath 所做的)。

那么我们可以直接使用我们的索引:

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 个嵌套循环。