我想将字符串中包含的字母的索引转换为整数值。尝试读取头文件,但找不到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)
感谢任何帮助。
答案 0 :(得分:66)
编辑/更新:
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(of string: Self) -> 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")
}
答案 1 :(得分:10)
适用于 Xcode 13 和 Swift 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
}
函数 func distance(from start: String.Index, to end: String.Index) -> String.IndexDistance
返回一个 IndexDistance
,它只是 typealias
的 Int
答案 2 :(得分:4)
快捷键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
答案 3 :(得分:2)
encodedOffset
已从 Swift 4.2 中弃用。
弃用消息:
encodedOffset
已被弃用,因为大多数常用用法都不正确。使用utf16Offset(in:)
实现相同的行为。
因此我们可以像这样使用utf16Offset(in:)
:
var str = "abcdefgc"
let index = str.index(of: "c")?.utf16Offset(in: str) // Result: 2
答案 4 :(得分:1)
搜索这样的索引时
⛔️ guard let index = (positions.firstIndex { position <= $0 }) else {
它被视为Array.Index。您必须为编译器提供一个想要整数的提示
✅ guard let index: Int = (positions.firstIndex { position <= $0 }) else {
答案 5 :(得分:0)
要基于index执行字符串操作,您不能使用传统的索引数字方法执行此操作。因为swift.index是由indexs函数检索的,并且不是Int类型。即使String是一个字符数组,我们仍然无法按索引读取元素。
这令人沮丧。
因此,要创建字符串的每个偶数字符的新子字符串,请检查以下代码。
let mystr = "abcdefghijklmnopqrstuvwxyz"
let mystrArray = Array(mystr)
let strLength = mystrArray.count
var resultStrArray : [Character] = []
var i = 0
while i < strLength {
if i % 2 == 0 {
resultStrArray.append(mystrArray[i])
}
i += 1
}
let resultString = String(resultStrArray)
print(resultString)
输出:acegikmoqsuwy
预先感谢
答案 6 :(得分:0)
Here is an extension,可让您以Int
而不是String.Index
的值访问子字符串的范围:
import Foundation
/// This extension is available at
/// https://gist.github.com/zackdotcomputer/9d83f4d48af7127cd0bea427b4d6d61b
extension StringProtocol {
/// Access the range of the search string as integer indices
/// in the rendered string.
/// - NOTE: This is "unsafe" because it may not return what you expect if
/// your string contains single symbols formed from multiple scalars.
/// - Returns: A `CountableRange<Int>` that will align with the Swift String.Index
/// from the result of the standard function range(of:).
func countableRange<SearchType: StringProtocol>(
of search: SearchType,
options: String.CompareOptions = [],
range: Range<String.Index>? = nil,
locale: Locale? = nil
) -> CountableRange<Int>? {
guard let trueRange = self.range(of: search, options: options, range: range, locale: locale) else {
return nil
}
let intStart = self.distance(from: startIndex, to: trueRange.lowerBound)
let intEnd = self.distance(from: trueRange.lowerBound, to: trueRange.upperBound) + intStart
return Range(uncheckedBounds: (lower: intStart, upper: intEnd))
}
}
请注意,这可能会导致怪异,这就是Apple选择加倍努力的原因。 (尽管这是一个值得商design的设计决策-仅通过使其变得困难来隐藏危险的东西...)
您可以在String documentation from Apple中阅读更多内容,但tldr的原因是这些“索引”实际上是特定于实现的。它们表示由操作系统呈现后的字符串索引,因此可以根据所使用的Unicode规范版本在操作系统之间进行转换。这意味着按索引访问值不再是固定时间的操作,因为必须对数据运行UTF规范才能确定字符串中的正确位置。这些索引也不会与NSString生成的值对齐(如果您将其桥接),也不会与基础UTF标量中的索引对齐。警告开发人员。