Как работает строка.Индекс работа в 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)


Они действительно смущали меня сначала, поэтому я начал играть с ними, пока не понял их. Я добавляю ответ ниже, чтобы показать, как они используются.

782   2  

2 ответов:

enter image description here

во всех приведенных ниже примерах используется

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

    Ничего не найдено.