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

2uluyalo  于 12个月前  发布在  Swift
关注(0)|答案(9)|浏览(136)

我想将字符串中包含的字母的索引转换为整数值。试图读取头文件,但我找不到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)

任何帮助都很感激。

lzfw57am

lzfw57am1#

编辑/更新:

Xcode 11 · Swift 5.1以上

extension StringProtocol {
    func distance(of element: Element) -> Int? { firstIndex(of: element)?.distance(in: self) }
    func distance<S: StringProtocol>(of string: S) -> Int? { range(of: string)?.lowerBound.distance(in: self) }
}
extension Collection {
    func distance(to index: Index) -> Int { distance(from: startIndex, to: index) }
}
extension String.Index {
    func distance<S: StringProtocol>(in string: S) -> Int { string.distance(to: self) }
}

Playground测试

let letters = "abcdefg"

let char: Character = "c"
if let distance = letters.distance(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 string = "cde"
if let distance = letters.distance(of: string) {
    print("string \(string) was found at position #\(distance)")   // "string cde was found at position #2\n"
} else {
    print("string \(string) was not found")
}
uxhixvfz

uxhixvfz2#

适用于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
}

函数func distance(from start: String.Index, to end: String.Index) -> String.IndexDistance返回IndexDistance,它只是Inttypealias

hzbexzde

hzbexzde3#

Swift 4酒店

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

注意:如果String包含相同的多个字符,则只取左数最近的一个

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

w6lpcovy4#

Swift 4.2弃用encodedOffset

弃用消息:encodedOffset已被弃用,因为大多数常见用法都不正确。使用utf16Offset(in:)实现相同的行为。
我们可以这样使用utf16Offset(in:)

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

x6492ojm5#

当搜索像这样的索引时

⛔️ guard let index = (positions.firstIndex { position <= $0 }) else {

它被视为Array.Index。你必须给予编译器一个提示,你想要一个整数

✅ guard let index: Int = (positions.firstIndex { position <= $0 }) else {
7kqas0il

7kqas0il6#

*Swift 5酒店

你可以先转换成字符数组,然后使用advanced(by:)转换成整数。

let myString = "Hello World"

if let i = Array(myString).firstIndex(of: "o") {
  let index: Int = i.advanced(by: 0)
  print(index) // Prints 4
}
t5zmwmid

t5zmwmid7#

基于索引的字符串运算,不能用传统的索引数值方法来实现。因为swift.index是由indices函数检索的,并且它不是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
先谢了

l7wslrjt

l7wslrjt8#

Here is an extension,它允许你访问子字符串的边界为Int s,而不是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))
    }
}

只是要知道,这可能会导致怪异,这就是为什么苹果选择让它变得困难。(虽然这是一个有争议的设计决策-通过使其变得困难来隐藏危险的事情......)
您可以在String documentation from Apple中阅读更多内容,但tldr是因为这些“索引”实际上是特定于实现的。它们表示字符串在被操作系统渲染后的索引,因此可以根据所使用的Unicode规范的版本从操作系统转移到操作系统。这意味着通过索引访问值不再是一个常数时间操作,因为UTF规范必须在数据上运行以确定字符串中的正确位置。这些索引也不会与NSString生成的值对齐(如果您桥接到它),或者与底层UTF标量的索引对齐。开发人员注意事项。

flmtquvp

flmtquvp9#

如果你得到了一个“索引超出界限”的错误。你可以试试这个方法。使用Swift 5

extension String{

   func countIndex(_ char:Character) -> Int{
        var count = 0
        var temp = self
  
        for c in self{
            
            if c == char {
               
                //temp.remove(at: temp.index(temp.startIndex,offsetBy:count))
                //temp.insert(".", at: temp.index(temp.startIndex,offsetBy: count))
                
                return count

            }
            count += 1
         }
        return -1
    }
}

相关问题