Для этого нет встроенных функций.Вы можете обернуть это в пользовательский итератор, но тогда вы будете инкапсулировать только те же вычисления в другом месте, так что это не ответ:)
Сложность кода
Однако вы можете улучшитьпроизводительность вашего текущего кода:
greeting.index(greeting.startIndex, offsetBy: intIndex)
- Это рассчитает индекс от
startIndex
до результирующего индекса для каждой итерации цикла. - Вычисление индекса с помощью
index(_:offsetBy:)
на самом деле представляет собой просто еще один цикл, в котором +1
каждый индекс.Нет O(1)
способа "вычислить" индекс;он обнаруживается циклом в O(n)
Таким образом, ваш собственный внешний цикл является линейным с O(n)
для n
итераций, по одному на каждый символ.
Тогда вычисление индекса с помощью внутреннего цикла означает, что есть 1+2+3+4+5+6+...n = (n^2 + n)/2
итераций, где n
- это intIndex
в этом случае.
Это означает, что алгоритм имеет сложность *ручная стирка * карусель O(n + n^2)
.Квадратичная часть проблематична!
Лучший подход
Вы можете снизить сложность до 2 операций за итерацию или O(2n)
.Просто сохраните ранее вычисленный индекс в памяти и самостоятельно добавьте +1, избегая повторного вычисления с нуля.
Вот код:
let greeting = "Hello"
var index = greeting.startIndex
for char in greeting {
let indexAfterCurrentIndex = greeting.index(after: index)
print(greeting[indexAfterCurrentIndex...])
index = indexAfterCurrentIndex
}
Все еще не простое и встроенное решение, но выс таким же успехом можно обернуть этот более эффективный алгоритм и готово!
extension String {
func forEachCharacterWithIndex(iterator: (String.Index, Character) -> Void) {
var currIndex = self.startIndex
for char in self {
iterator(currIndex, char)
currIndex = self.index(after: currIndex)
}
}
}
let greeting = "Hello"
greeting.forEachCharacterWithIndex { (index, char) in
let indexAfterCurrentIndex = greeting.index(after: index)
print(greeting[indexAfterCurrentIndex...])
}