How to convert “Index” to type “Int” in Swift?

前端 未结 6 1952
旧巷少年郎
旧巷少年郎 2020-12-01 10:19

I want to convert the index of a letter contained within a string to an integer value. Attempted to read the header files but I cannot find the type for Index,

6条回答
  •  伪装坚强ぢ
    2020-12-01 10:36

    Here is an extension that will let you access the bounds of a substring as Ints instead of String.Index values:

    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` that will align with the Swift String.Index
        ///     from the result of the standard function range(of:).
        func countableRange(
            of search: SearchType,
            options: String.CompareOptions = [],
            range: Range? = nil,
            locale: Locale? = nil
        ) -> CountableRange? {
            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))
        }
    }
    

    Just be aware that this can lead to weirdness, which is why Apple has chosen to make it hard. (Though that's a debatable design decision - hiding a dangerous thing by just making it hard...)

    You can read more in the String documentation from Apple, but the tldr is that it stems from the fact that these "indices" are actually implementation-specific. They represent the indices into the string after it has been rendered by the OS, and so can shift from OS-to-OS depending on what version of the Unicode spec is being used. This means that accessing values by index is no longer a constant-time operation, because the UTF spec has to be run over the data to determine the right place in the string. These indices will also not line up with the values generated by NSString, if you bridge to it, or with the indices into the underlying UTF scalars. Caveat developer.

提交回复
热议问题