Как работает строка.Индекс работа в Swift
я обновлял некоторые из моих старых кодов и ответов с помощью Swift 3, но когда я добрался до Swift Strings и индексирования, было больно понимать вещи.
в частности, я пытался следующее:
let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5) // error
где вторая строка дает мне следующую ошибку
'advancedBy' недоступен: для продвижения индекса на n шагов вызовите 'index (_: offsetBy:)' на экземпляре CharacterView, который произвел индекс.
Я вижу String имеет следующие методы.
str.index(after: String.Index)
str.index(before: String.Index)
str.index(String.Index, offsetBy: String.IndexDistance)
str.index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)
Они действительно смущали меня сначала, поэтому я начал играть с ними, пока не понял их. Я добавляю ответ ниже, чтобы показать, как они используются.
2 ответов:
во всех приведенных ниже примерах используется
var str = "Hello, playground"
startIndexиendIndex
startIndex- это индекс первого символаendIndexиндекс после последний символ.пример
// character str[str.startIndex] // H str[str.endIndex] // error: after last character // range let range = str.startIndex..<str.endIndex str[range] // "Hello, playground"С Swift 4's однобоко диапазоны диапазон может быть упрощен до одного из следующих формы.
let range = str.startIndex... let range = ..<str.endIndexя буду использовать полную форму в следующих примерах для ясности, но для удобства чтения вы, вероятно, захотите использовать односторонние диапазоны в своем коде.
afterв:
index(after: String.Index)
afterотносится к индексу символа непосредственно после данного индекса.примеры
// character let index = str.index(after: str.startIndex) str[index] // "e" // range let range = str.index(after: str.startIndex)..<str.endIndex str[range] // "ello, playground"
beforeкак в:
index(before: String.Index)
beforeотносится к индексу символа непосредственно перед данным индексом.примеры
// character let index = str.index(before: str.endIndex) str[index] // d // range let range = str.startIndex..<str.index(before: str.endIndex) str[range] // Hello, playgroun
offsetByв:
index(String.Index, offsetBy: String.IndexDistance)
- The
offsetByзначение может быть положительным или отрицательным и начинает от данного индекса. Хотя это типаString.IndexDistance, вы можете придать емуInt.примеры
// character let index = str.index(str.startIndex, offsetBy: 7) str[index] // p // range let start = str.index(str.startIndex, offsetBy: 7) let end = str.index(str.endIndex, offsetBy: -6) let range = start..<end str[range] // play
limitedByв:
index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)
- The
limitedByполезно для того, чтобы убедиться, что смещение не приводит к выходу индекса за пределы. Это ограничивающий индекс. Поскольку смещение может превышать предел, этот метод возвращает необязательный параметр. Он возвращаетnilесли индекс находится вне границ.пример
// character if let index = str.index(str.startIndex, offsetBy: 7, limitedBy: str.endIndex) { str[index] // p }если смещение был
77вместо7, потомifзаявление было бы пропущено.почему строка.Индекс нужен?
было бы много проще использовать
Intиндекс для строк. Причина в том, что вы должны создать новыйString.Indexдля каждой строки является то, что символы в Swift не все одинаковой длины под капотом. Один быстрый символ может состоять из одной, двух или даже более кодовых точек Юникода. Таким образом, каждая уникальная строка необходимо рассчитать индексы его символов.возможно, чтобы скрыть эту сложность за расширением индекса Int, но я не хочу этого делать. Хорошо, когда тебе напоминают о том, что происходит на самом деле.
Swift 4 Полное Решение:
OffsetIndexableCollection (строка с использованием индекса Int)
https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-

Comments