[string] Swift에서 “Index”를 “Int”유형으로 변환하는 방법은 무엇입니까?

문자열에 포함 된 문자의 인덱스를 정수 값으로 변환하고 싶습니다. 헤더 파일을 읽으려고 시도했지만에 대한 유형을 찾을 수 없지만 메서드 (예 Index:)가있는 프로토콜을 준수하는 것으로 보입니다 .ForwardIndexTypedistanceTo

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)

도움을 주시면 감사하겠습니다.



답변

편집 / 업데이트 :

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) }
}

놀이터 테스트

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")
}


답변

스위프트 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


답변

encodedOffsetSwift 4.2 에서 더 이상 사용되지 않습니다. .

지원 중단 메시지 :
encodedOffset가장 일반적인 사용법이 올바르지 않아 더 이상 사용되지 않습니다. 사용하다utf16Offset(in:)동일한 동작을 달성하기 위해 합니다.

따라서 다음 utf16Offset(in:)과 같이 사용할 수 있습니다 .

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


답변

index를 기반으로 문자열 연산을 수행하려면 기존 인덱스 숫자 방식으로는 수행 할 수 없습니다. swift.index는 indices 함수에 의해 검색되고 Int 유형이 아니기 때문입니다. String이 문자의 배열이지만 인덱스로 요소를 읽을 수는 없습니다.

이것은 실망 스럽습니다.

따라서 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

미리 감사드립니다


답변

다음은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))
    }
}

이것이 기이함으로 이어질 수 있다는 점을 명심하십시오. 이것이 Apple이 그것을 어렵게 만들기로 선택한 이유입니다. (논쟁의 여지가있는 디자인 결정이긴하지만-어렵게 만들어 위험한 것을 숨기는 것 …)

AppleString 문서에서 더 많은 것을 읽을 수 있지만, tldr은 이러한 “인덱스”가 실제로 구현에 따라 다르다는 사실에서 비롯된 것입니다. 그것들은 OS에 의해 렌더링 된 후 문자열에 대한 색인을 나타내 므로 사용중인 유니 코드 사양의 버전에 따라 OS에서 OS로 이동할 수 있습니다. 즉, 문자열에서 올바른 위치를 결정하기 위해 데이터에 대해 UTF 사양을 실행해야하므로 인덱스로 값에 액세스하는 것이 더 이상 상수 시간 작업이 아닙니다. 이러한 인덱스는 NSString에 의해 생성 된 값이나 기본 UTF 스칼라에 대한 인덱스와 함께 정렬되지 않습니다. 주의 사항 개발자.


답변

이와 같은 색인을 검색 할 때

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

Array.Index로 처리됩니다. 컴파일러에게 정수를 원하는 단서를 제공해야합니다.

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


답변