Подтвердить что ты не робот

Как преобразовать "Индекс", чтобы ввести "Int" в Swift?

Я хочу преобразовать индекс буквы, содержащейся в строке, в целочисленное значение. Попытка прочитать файлы заголовков, но я не могу найти тип для Index, хотя он, похоже, соответствует протоколу ForwardIndexType с методами (например, distanceTo).

var letters = "abcdefg"
let index = letters.characters.indexOf("c")!

// ERROR: Cannot invoke initializer for type 'Int' with an argument list of type '(String.CharacterView.Index)'
let intValue = Int(index)  // I want the integer value of the index (e.g. 2)

Любая помощь приветствуется.

4b9b3361

Ответ 1

редактировать/обновление:

Xcode 10.2.x • Swift 5 или более поздняя версия

extension Collection where Element: Equatable {
    func indexDistance(of element: Element) -> Int? {
        guard let index = firstIndex(of: element) else { return nil }
        return distance(from: startIndex, to: index)
    }
}
extension StringProtocol {
    func indexDistance<S: StringProtocol>(of string: S) -> Int? {
        guard let index = range(of: string)?.lowerBound else { return nil }
        return distance(from: startIndex, to: index)
    }
}

Xcode 9 • Swift 4

let letters = "abcdefg"

if let index = letters.index(of: "c") {
    let distance = letters.distance(from: letters.startIndex, to: index)
    print("distance:", distance)
}

if let index = letters.range(of: "cde")?.lowerBound {
    let distance = letters.distance(from: letters.startIndex, to: index)
    print("distance:", distance)
}

Если вы хотите реализовать его как метод экземпляра Collection:

extension Collection where Element: Equatable {
    func indexDistance(of element: Element) -> Int? {
        guard let index = index(of: element) else { return nil }
        return distance(from: startIndex, to: index)
    }
}

extension StringProtocol where Index == String.Index {
    func indexDistance(of string: Self) -> Int? {
        guard let index = range(of: string)?.lowerBound else { return nil }
        return distance(from: startIndex, to: index)
    }
}

Тестирование игровой площадки

let letters = "abcdefg"

let char: Character = "c"
if let distance = letters.indexDistance(of: char) {
    print("character \(char) was found at position #\(distance)")   // "character c was found at position #2\n"
} else {
    print("character \(char) was not found")
}

let cde = "cde"
if let distance = letters.indexDistance(of: cde) {
    print("string \(cde) was found at position #\(distance)")   // "string cde was found at position #2\n"
} else {
    print("string \(string) was not found")
}

Xcode 8 • Swift 3

let letters = "abcdefg"
if let index = letters.characters.index(of: "c") {
    let distance = letters.distance(from: letters.startIndex, to: index)
    print("distance:", distance)
}

extension String {
    func indexDistance(of character: Character) -> Int? {
        guard let index = characters.index(of: character) else { return nil }
        return distance(from: startIndex, to: index)
    }
}

let letters = "abcdefg"
let char: Character = "c"
if let index = letters.indexDistance(of: char) {
    print("character \(char) was found at position #\(index)")   // "character c was found at position #2\n"
} else {
    print("character \(char) was not found")
}

Оригинальный ответ

Вам необходимо использовать метод distanceTo (index) относительно исходного начального индекса строки:

let intValue = letters.startIndex.distanceTo(index)

Вы также можете расширить String с помощью метода для возврата первого вхождения символа в строку следующим образом:

extension String {
    func indexDistanceOfFirst(character character: Character) -> Int? {
        guard let index = characters.indexOf(character) else { return nil }
        return startIndex.distanceTo(index)
    }
}

let letters = "abcdefg"
let char: Character = "c"
if let index = letters.indexDistanceOfFirst(character: char) {
    print("character \(char) was found at position #\(index)")   // "character c was found at position #2\n"
} else {
    print("character \(char) was not found")
}

Ответ 2

Swift 4

var str = "abcdefg"
let index = str.index(of: "c")?.encodedOffset // Result: 2

Примечание. Если строка содержит несколько одинаковых символов, она просто получит ближайший слева

var str = "abcdefgc"
let index = str.index(of: "c")?.encodedOffset // Result: 2