如何在Swift中将"Index"转换为"Int"类型?

Chr*_*her 74 string 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)
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏.

Leo*_*bus 74

Xcode 9•Swift 4或更高版本

extension StringProtocol {
    func indexDistance(of element: Element) -> Int? { firstIndex(of: element)?.distance(in: self) }
    func indexDistance<S: StringProtocol>(of string: S) -> Int? { range(of: string)?.lowerBound.distance(in: self) }
}
extension String.Index {
    func distance<S: StringProtocol>(in string: S) -> Int { string.distance(from: string.startIndex, to: self) }
}
Run Code Online (Sandbox Code Playgroud)
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)
    }
}
Run Code Online (Sandbox Code Playgroud)
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")
}
Run Code Online (Sandbox Code Playgroud)

Swift 4中另一种可能的方法是返回索引__CODE__:

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 \(cde) was not found")
}
Run Code Online (Sandbox Code Playgroud)
extension StringProtocol {
    func indexDistance(of element: Element) -> Int? { firstIndex(of: element)?.distance(in: self) }
    func indexDistance<S: StringProtocol>(of string: S) -> Int? { range(of: string)?.lowerBound.distance(in: self) }
}
extension String.Index {
    func distance<S: StringProtocol>(in string: S) -> Int { string.distance(from: string.startIndex, to: self) }
}
Run Code Online (Sandbox Code Playgroud)
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)
    }
}
Run Code Online (Sandbox Code Playgroud)

Xcode 8•Swift 3

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")
}
Run Code Online (Sandbox Code Playgroud)
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 \(cde) was not found")
}
Run Code Online (Sandbox Code Playgroud)
extension StringProtocol {
    func indexDistance(of element: Element) -> Int? { firstIndex(of: element)?.distance(in: self) }
    func indexDistance<S: StringProtocol>(of string: S) -> Int? { range(of: string)?.lowerBound.distance(in: self) }
}
extension String.Index {
    func distance<S: StringProtocol>(in string: S) -> Int { string.distance(from: string.startIndex, to: self) }
}
Run Code Online (Sandbox Code Playgroud)

老答案

您需要使用与原始字符串起始索引相关的distanceTo(index)方法:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用方法扩展String以返回字符串中第一次出现的字符,如下所示:

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")
}
Run Code Online (Sandbox Code Playgroud)
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 \(cde) was not found")
}
Run Code Online (Sandbox Code Playgroud)

  • 我很困惑为什么他们不会决定创建一个返回数组元素的整数值索引的函数.smh (21认同)
  • 使简单的事情变得不必要的复杂:( (10认同)
  • 并非所有字符都可以存储在单个字节中.您应该花一些时间阅读Swift String文档 (5认同)
  • Tbh我正在尝试获取常规数组元素的整数值索引,而不是字符串. (3认同)
  • 如果您的数组元素符合 equatable 协议,那应该很简单 (2认同)
  • 如果将 String 转换为 NSString,则可以访问更旧、更简单的 API 进行数字索引,**但是**如果必须与多个字符组合成单个符号的 UTF 序列交互,您的代码绝对会出现错误或中断。正如 @LeoDabus 所建议的,请参阅 Swift String 文档以获取有关此问题的更多信息。或者,如果你想挖出你的眼睛,请尝试阅读 UTF 规范...... (2认同)

Eri*_*187 13

适用于Xcode 13Swift 5

let myString = "Hello World"

if let i = myString.firstIndex(of: "o") {
  let index: Int = myString.distance(from: myString.startIndex, to: i)
  print(index) // Prints 4
}
Run Code Online (Sandbox Code Playgroud)

该函数func distance(from start: String.Index, to end: String.Index) -> String.IndexDistance返回一个IndexDistance只是一个typealiasforInt


小智 5

斯威夫特4

var str = "abcdefg"
let index = str.index(of: "c")?.encodedOffset // Result: 2
Run Code Online (Sandbox Code Playgroud)

注意:如果String包含相同的多个字符,则只会从左侧获得最接近的一个字符

var str = "abcdefgc"
let index = str.index(of: "c")?.encodedOffset // Result: 2
Run Code Online (Sandbox Code Playgroud)

  • 不要使用编码偏移。**encodedOffset 已弃用:encodedOffset 已被弃用,因为最常见的用法是不正确的。** 尝试 `"".index(of: "")?.encodedOffset // 16` (7认同)
  • 在Swift 4.2中不建议使用encodeOffset (4认同)