Swift 2.2 在 Swift 3 中递减特定的 for 循环

Swift 2.2 decrementing specific for loop in Swift 3

我的任务是将 iOS 应用程序重构为 Swift 3。但是,在 C 风格中有一个 for 循环,它不仅仅循环一个向后排列(必须向后排列)。

这是示例代码。原理是一样的。

let array = ["hello", "world", nil, "foo", nil, "bar", "Peter Griffin"]
var threeLetterWords = 0
for var i = array.count-1; i >= 0 && array[i].characters.count == 3; --i, ++threeLetterWords { }
print("Found words: \(threeLetterWords)") // should say `Found words: 2`

我尝试使用 stride(from:through:by:),但我无法增加 threeLetterWords,因为在循环中增加它似乎很重要。有什么想法吗?

//for var i = array.count-1; i >= 0 && array[i].characters.count == 3; --i, ++threeLetterWords { }

for i in stride(from: (array.count-1), through: 0, by: -1) {
    threeLetterWords += 1

    if (array[i]?.characters.count == 3) {
        break
    }
}

您可以使用反转的数组索引并为字符数添加一个 where 子句:

let array = ["hello", "world", nil, "foo", nil, "bar", "Peter Griffin"]
var threeLetterWords = 0

for index in array.indices.reversed() where array[index]?.characters.count == 3 {
    threeLetterWords += 1
}

print("Found words: \(threeLetterWords)") // should say `Found words: 2`

您的代码没有计算数组中 3 个字母的单词的数量。它正在计算数组末尾的 3 个字母单词的数量。它将 return 0 作为您的示例输入数组。

当 C 风格的 for 循环非常复杂时,最终的回退解决方案是将其转换为 while 循环。任何 C 风格的 for 循环都可以机械地转换成等效的 while 循环,这意味着即使您不完全理解也可以做到它在做什么。

这个 for 循环:

for initialization; condition; increment {
    // body
}

相当于:

initialization
while condition {
    // body
    increment
}

因此,您的代码等同于:

let array = ["hello", "world", nil, "foo", nil, "bar", "Peter Griffin"]
var threeLetterWords = 0

var i = array.count - 1
while i >= 0 && array[i]?.characters.count == 3 {
    i -= 1
    threeLetterWords += 1
}
print("Found words: \(threeLetterWords)") // says `Found words: 0`

下面是如何使用 for 循环和 guard 来执行与您的代码等效的操作:

let array = ["hello", "world", nil, "foo", nil, "bar", "Peter Griffin"]
var num3LetterWords = 0

for word in array.reversed() {
    guard word?.characters.count == 3 else { break }
    num3LetterWords += 1
}

print(num3LetterWords)

这里的每个人都非常不必要地将其复杂化。

let words = ["hello", "world", nil, "foo", nil, "bar", "Peter Griffin"]

var num3LetterWords = 0

for word in words.reversed() {
    if (word?.characters.count == 3) { num3LetterWords += 1 }
}

print(num3LetterWords)