Swift 프로그래밍 언어에서 문자열의 n 번째 문자 가져 오기


419

문자열의 n 번째 문자를 얻으려면 어떻게해야합니까? []행운이없이 bracket ( ) 접근 자를 시도했습니다 .

var string = "Hello, world!"

var firstChar = string[0] // Throws error

오류 : '아래 첨자'를 사용할 수 없습니다 : Int로 문자열을 첨자 할 수 없습니다. 설명서 주석을 참조하십시오.


1
“Int로 문자열을 첨자화할 수 없습니다. 토론을위한 설명서 주석을 참조하십시오”라는 오류 메시지는 github.com/apple/swift/blob/master/stdlib/public/core/…를
andrewdotn

사용 var firstChar = string.index(string.startIndex, offsetBy: 0)대신에
Sazzad Hissain 칸에게

@SazzadHissainKhan 문자가 아닌 문자열 인덱스가됩니다. 왜 그렇게 간단하지 string.startIndex않습니까? 첫 번째 문자 string[string.startIndex] 또는 단순히 string.first. 첫 번째 방법은 문자열이 비어 있는지 먼저 확인해야한다는 것입니다. 두 번째 방법은 선택 사항을 반환합니다.
Leo Dabus

답변:


567

주의 : Swift 4 및 Swift 5의 올바른 구현에 대해서는 Leo Dabus의 답변 을 참조하십시오 .

스위프트 4 이상

Substring유형은 원본 문자열과 스토리지를 공유하여 하위 문자열을 더 빠르고 효율적으로 만들기 위해 Swift 4에 도입되었으므로 하위 스크립트 함수가 반환해야합니다.

여기서 사용해보십시오

extension StringProtocol {
    subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] }
    subscript(range: Range<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: ClosedRange<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: PartialRangeFrom<Int>) -> SubSequence { self[index(startIndex, offsetBy: range.lowerBound)...] }
    subscript(range: PartialRangeThrough<Int>) -> SubSequence { self[...index(startIndex, offsetBy: range.upperBound)] }
    subscript(range: PartialRangeUpTo<Int>) -> SubSequence { self[..<index(startIndex, offsetBy: range.upperBound)] }
}

을 변환하려면 SubstringString, 당신은 간단하게 할 수 String(string[0..2])있지만, 당신은 당신이하려는 경우 주변 하위 문자열 유지하는 것을해야한다. 그렇지 않으면을 유지하는 것이 더 효율적 Substring입니다.

누군가이 두 확장을 하나로 병합하는 좋은 방법을 알아낼 수 있다면 좋을 것입니다. 방법이 존재하지 StringProtocol 않기 때문에 성공하지 않고 확장 을 시도 index했습니다. 참고 :이 답변은 이미 편집되었으며 올바르게 구현되어 이제 하위 문자열에서도 작동합니다. StringProtocol 유형을 첨자화할 때 충돌을 피하려면 유효한 범위를 사용해야합니다. 범위를 벗어난 값으로 충돌하지 않는 범위를 가진 첨자를 위해이 구현을 사용할 수 있습니다


왜 이것이 내장되어 있지 않습니까?

오류 메시지에 "토론을위한 설명서 주석 참조"가 표시 됩니다. Apple은 UnavailableStringAPIs.swift 파일에 다음 설명을 제공합니다 .

정수로 첨자 문자열을 사용할 수 없습니다.

" i문자열의 문자 "개념은 라이브러리 및 시스템 구성 요소에 따라 다르게 해석됩니다. 사용 사례 및 관련 API에 따라 올바른 해석을 선택해야하므로 String 정수로 첨자를 사용할 수 없습니다.

Swift는 문자열 안에 저장된 문자 데이터에 액세스하는 여러 가지 방법을 제공합니다.

  • String.utf8문자열에서 UTF-8 코드 단위의 모음입니다. 문자열을 UTF-8로 변환 할 때이 API를 사용하십시오. 대부분의 POSIX API는 UTF-8 코드 단위로 문자열을 처리합니다.

  • String.utf16문자열로 된 UTF-16 코드 단위의 모음입니다. 대부분의 Cocoa 및 Cocoa touch API는 문자열을 UTF-16 코드 단위로 처리합니다. 예를 들어, UTF-16 코드 단위로 하위 문자열 오프셋 및 길이 NSRange와 함께 사용 NSAttributedStringNSRegularExpression저장 되는 인스턴스입니다 .

  • String.unicodeScalars유니 코드 스칼라의 모음입니다. 문자 데이터의 저수준 조작을 수행 할 때이 API를 사용하십시오.

  • String.characters 사용자가 인식 한 문자의 근사치 인 확장 된 grapheme 클러스터 모음입니다.

사람이 읽을 수있는 텍스트가 포함 된 문자열을 처리 할 때는 문자 별 처리를 최대한 피해야합니다. 대신에 고급 로케일 구분 유니 코드 알고리즘을 사용하십시오 (예 String.localizedStandardCompare(): String.localizedLowercaseString, String.localizedStandardRangeOfString()등).


4
Cannot find an overload for 'advance' that accepts an argument list of type '(String.Index, T)'... String.IndexInt호환되지 않습니다.

7
당신이 볼 경우 Cannot subscript a value of type 'String'...:이 답변 확인 stackoverflow.com/a/31265316/649379
SoftDesigner

24
이것을 사용하려고하면 얻을 수 Ambiguous use of 'subscript'있습니다.
jowie

18
경고! 아래 확장은 끔찍하게 비효율적입니다. 문자열이 정수로 액세스 될 때마다 시작 색인을 진행시키는 O (n) 함수가 실행됩니다. 다른 선형 루프 내에서 선형 루프를 실행하면 실수로 for for loop가 O (n2)임을 의미합니다. 스트링 길이가 길어질수록이 루프가 걸리는 시간은 2 차적으로 증가합니다. 대신 문자의 문자열 컬렉션을 사용할 수 있습니다.
ignaciohugog 2016 년

2
fatal error: Can't form a Character from an empty String
Devin B

341

스위프트 5.2

let str = "abcdef"
str[1 ..< 3] // returns "bc"
str[5] // returns "f"
str[80] // returns ""
str.substring(fromIndex: 3) // returns "def"
str.substring(toIndex: str.length - 2) // returns "abcd"

이 문자열 확장을 프로젝트에 추가해야합니다 (완전히 테스트 됨).

extension String {

    var length: Int {
        return count
    }

    subscript (i: Int) -> String {
        return self[i ..< i + 1]
    }

    func substring(fromIndex: Int) -> String {
        return self[min(fromIndex, length) ..< length]
    }

    func substring(toIndex: Int) -> String {
        return self[0 ..< max(0, toIndex)]
    }

    subscript (r: Range<Int>) -> String {
        let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
                                            upper: min(length, max(0, r.upperBound))))
        let start = index(startIndex, offsetBy: range.lowerBound)
        let end = index(start, offsetBy: range.upperBound - range.lowerBound)
        return String(self[start ..< end])
    }
}

Swift가 항상이 문제에 대한 해결책을 항상 가지고 있었지만 (아래에 제공 한 String 확장명 없음) 여전히 확장명을 사용하는 것이 좋습니다 . 왜? String의 구문이 거의 모든 릴리스에서 변경되는 초기 버전의 Swift에서 수십 시간의 고통스러운 마이그레이션을 절약했기 때문에 전체 프로젝트를 리팩토링하는 대신 확장 구현을 업데이트하기 만하면됩니다. 선택하십시오.

let str = "Hello, world!"
let index = str.index(str.startIndex, offsetBy: 4)
str[index] // returns Character 'o'

let endIndex = str.index(str.endIndex, offsetBy:-2)
str[index ..< endIndex] // returns String "o, worl"

String(str.suffix(from: index)) // returns String "o, world!"
String(str.prefix(upTo: index)) // returns String "Hell"

다음 range.upperBound - range.lowerBound으로 변경range.count
Leo Dabus

원래 질문의 일부는 아니지만 ...이 지원을 할당하면 좋을 것입니다. 예를 들어, s [i] = "a":).
Chris Prince

2
Swift 4.2 아래 첨자는 다시 사용할 수 없다고 생각합니다. '첨자'를 사용할 수 없음 : Int가 포함 된 문자열을 첨자화할 수 없습니다. 토론에 대한 설명서 설명을 참조하십시오.
C0D3

2
@ChrisPrinceextension StringProtocol where Self: RangeReplaceableCollection { subscript(offset: Int) -> Element { get { return self[index(startIndex, offsetBy: offset)] } set { let start = index(startIndex, offsetBy: offset) replaceSubrange(start..<index(after: start), with: [newValue]) } } }
Leo

이것은 내장 함수 여야합니다
Ammar Mujeeb

150

방금이 깔끔한 해결 방법을 생각해 냈습니다.

var firstChar = Array(string)[0]

2
UTF8 또는 ASCII 인코딩 문자열을 알고있는 일반적인 경우에 대한 빠른 해결 방법입니다. 문자열이 둘 이상의 바이트를 사용하는 인코딩에 포함되지 않도록하십시오.
Jeff Hay

47
첫 번째 문자를 얻기 위해 전체 문자열을 복사 할 때 매우 비효율적입니다. string [string을 사용하십시오. Sulthan이 지적한대로 0 대신 startIndex].
Bjorn

6
포장을 벗긴 문자열 : var firstChar = Array(string!)[0]그렇지 않으면 말할 것이다add arrayLiteral
모하마드 자이드 파탄

2
나는 이것이 사실이라고 생각하지 않습니다. Array의 어떤 초기화 프로그램이 먼저 사용되는지 확실하지 않습니다 (그리고 SequenceType 이니셜 라이저가 문자열의 문자를 Array의 개별 구성 요소로 수집한다고 가정합니다). 이것은 전혀 명시 적이 지 않으며 향후 유형 변환없이 수정 될 수 있습니다. [string] .first를 통해 배열에 속기를 사용하는 경우에도 작동하지 않습니다. @Sulthan의 솔루션은 구운 인덱스 값을 사용하는 것이 가장 좋습니다. 여기서 일어나는 일이 훨씬 더 분명합니다.
TheCodingArt

2
와우, 컴파일러 세그먼트 결함!
Frank

124

정수만 사용하여 인덱싱하지 않고을 사용 String.Index합니다. 대부분 선형 복잡성. 범위를 작성 String.Index하고이를 사용하여 하위 문자열을 얻을 수도 있습니다 .

스위프트 3.0

let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.index(before: someString.endIndex)]
let charAtIndex = someString[someString.index(someString.startIndex, offsetBy: 10)]

let range = someString.startIndex..<someString.index(someString.startIndex, offsetBy: 10)
let substring = someString[range]

스위프트 2.x

let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.endIndex.predecessor()]
let charAtIndex = someString[someString.startIndex.advanceBy(10)]

let range = someString.startIndex..<someString.startIndex.advanceBy(10)
let subtring = someString[range]

한 문자열에서 다른 문자열로 생성 된 인덱스 (또는 범위)는 사용할 수 없습니다.

let index10 = someString.startIndex.advanceBy(10)

//will compile
//sometimes it will work but sometimes it will crash or result in undefined behaviour
let charFromAnotherString = anotherString[index10]

7
String인덱스는 문자열에 고유합니다. 이것은 다른 문자열이 다른 다중 장치 UTF-16 Characters및 / 또는 다른 위치에있을 수 있으므로 UTF-16 단위 색인이 일치하지 않거나 다중 장치 UTF-16 내부의 끝 또는 지점을 벗어날 수 있기 때문 Character입니다.
zaph

@Zaph 분명합니다.
Sulthan

3
"때때로 충돌이 발생하거나 정의되지 않은 동작이 발생합니다"라고 말하는 이유를 설명합니다. 아마 그렇게하지 말라고하는 것이 더 좋을 것입니다.
zaph

1
@Sulthan는 ..지금 ..<(과제에에 range)
아론 Brager

3
@CajunLuke이 의견을 게시 한 지 오래되었다는 것을 알고 있지만 이 답변을 살펴보십시오 . 사용 가능var lastChar = string[string.endIndex.predecessor()]
David L

122

Xcode 11 • 스위프트 5.1

StringProtocol을 확장하여 아래 첨자도 아래 첨자를 사용할 수 있습니다.

extension StringProtocol {
    subscript(_ offset: Int)                     -> Element     { self[index(startIndex, offsetBy: offset)] }
    subscript(_ range: Range<Int>)               -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
    subscript(_ range: ClosedRange<Int>)         -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
    subscript(_ range: PartialRangeThrough<Int>) -> SubSequence { prefix(range.upperBound.advanced(by: 1)) }
    subscript(_ range: PartialRangeUpTo<Int>)    -> SubSequence { prefix(range.upperBound) }
    subscript(_ range: PartialRangeFrom<Int>)    -> SubSequence { suffix(Swift.max(0, count-range.lowerBound)) }
}

extension LosslessStringConvertible {
    var string: String { .init(self) }
}

extension BidirectionalCollection {
    subscript(safe offset: Int) -> Element? {
        guard !isEmpty, let i = index(startIndex, offsetBy: offset, limitedBy: index(before: endIndex)) else { return nil }
        return self[i]
    }
}

테스팅

let test = "Hello USA 🇺🇸!!! Hello Brazil 🇧🇷!!!"
test[safe: 10]   // "🇺🇸"
test[11]   // "!"
test[10...]   // "🇺🇸!!! Hello Brazil 🇧🇷!!!"
test[10..<12]   // "🇺🇸!"
test[10...12]   // "🇺🇸!!"
test[...10]   // "Hello USA 🇺🇸"
test[..<10]   // "Hello USA "
test.first   // "H"
test.last    // "!"

// Subscripting the Substring
 test[...][...3]  // "Hell"

// Note that they all return a Substring of the original String.
// To create a new String from a substring
test[10...].string  // "🇺🇸!!! Hello Brazil 🇧🇷!!!"

"self [index (startIndex, offsetBy : i)]"란 무엇입니까? "self [i]"는 어떻게 작동합니까?
allenlinli

1
레오, 해결책에 감사드립니다! 방금 (오늘) Swift 2.3에서 3으로 전환했으며 솔루션 첨자 (범위 : Range <Int>)에 "추가 인수 'limitedBy'in call"오류가 발생합니다. 무엇이 잘못 될 수 있다고 생각하십니까?
Ahmet Akkök

@ AhmetAkkök 코드를 변경하지 않았습니까?
Leo Dabus

1
@ 레오 전체 프로젝트를 변환하지는 않았지만 확장 프로그램이 아닌 앱에서 앱과 확장 프로그램에 대해 프로세스를 반복했으며 이제는 정상적으로 작동합니다. 당신의 도움은 대단히 감사합니다!
Ahmet Akkök

이것은 매우 복잡한 코드입니다. return String(Array(characters)[range])Swift 3에서 하는 것의 장점은 무엇입니까 ?
Dan Rosenstark

68

스위프트 4

let str = "My String"

인덱스의 문자열

let index = str.index(str.startIndex, offsetBy: 3)
String(str[index])    // "S"

부분 문자열

let startIndex = str.index(str.startIndex, offsetBy: 3)
let endIndex = str.index(str.startIndex, offsetBy: 7)
String(str[startIndex...endIndex])     // "Strin"

첫 n 자

let startIndex = str.index(str.startIndex, offsetBy: 3)
String(str[..<startIndex])    // "My "

마지막 n 자

let startIndex = str.index(str.startIndex, offsetBy: 3)
String(str[startIndex...])    // "String"

스위프트 2와 3

str = "My String"

** 지수 문자열 **

스위프트 2

let charAtIndex = String(str[str.startIndex.advancedBy(3)])  // charAtIndex = "S"

스위프트 3

str[str.index(str.startIndex, offsetBy: 3)]

Index to Index to SubString

스위프트 2

let subStr = str[str.startIndex.advancedBy(3)...str.startIndex.advancedBy(7)] // subStr = "Strin"

스위프트 3

str[str.index(str.startIndex, offsetBy: 3)...str.index(str.startIndex, offsetBy: 7)]

첫 n 자

let first2Chars = String(str.characters.prefix(2)) // first2Chars = "My"

마지막 n 자

let last3Chars = String(str.characters.suffix(3)) // last3Chars = "ing"

24

Xcode 7 GM Seed의 Swift 2.0

var text = "Hello, world!"

let firstChar = text[text.startIndex.advancedBy(0)] // "H"

n 번째 문자의 경우 0을 n-1로 바꾸십시오.

편집 : 스위프트 3.0

text[text.index(text.startIndex, offsetBy: 0)]


nb 문자열에서 특정 문자를 잡는 간단한 방법이 있습니다

예 : let firstChar = text.characters.first


23

Cannot subscript a value of type 'String'...이 확장명을 사용하는 경우 :

스위프트 3

extension String {
    subscript (i: Int) -> Character {
        return self[self.characters.index(self.startIndex, offsetBy: i)]
    }

    subscript (i: Int) -> String {
        return String(self[i] as Character)
    }

    subscript (r: Range<Int>) -> String {
        let start = index(startIndex, offsetBy: r.lowerBound)
        let end = index(startIndex, offsetBy: r.upperBound)
        return self[start..<end]
    }

    subscript (r: ClosedRange<Int>) -> String {
        let start = index(startIndex, offsetBy: r.lowerBound)
        let end = index(startIndex, offsetBy: r.upperBound)
        return self[start...end]
    }
}

스위프트 2.3

extension String {
    subscript(integerIndex: Int) -> Character {
        let index = advance(startIndex, integerIndex)
        return self[index]
    }

    subscript(integerRange: Range<Int>) -> String {
        let start = advance(startIndex, integerRange.startIndex)
        let end = advance(startIndex, integerRange.endIndex)
        let range = start..<end
        return self[range]
    }
}

출처 : http://oleb.net/blog/2014/07/swift-strings/


19

스위프트 2.2 솔루션 :

엑스 코드 7 다음 확장 작업은 이것의 조합 용액 2.0 스위프트 신택스 변환.

extension String {
    subscript(integerIndex: Int) -> Character {
        let index = startIndex.advancedBy(integerIndex)
        return self[index]
    }

    subscript(integerRange: Range<Int>) -> String {
        let start = startIndex.advancedBy(integerRange.startIndex)
        let end = startIndex.advancedBy(integerRange.endIndex)
        let range = start..<end
        return self[range]
    }
}

14

신속한 문자열 클래스는 UTF 문자에 대한 기본 지원으로 인해 특정 색인에서 문자를 가져 오는 기능을 제공하지 않습니다. 메모리에서 UTF 문자의 가변 길이는 문자로 직접 점프하는 것을 불가능하게합니다. 즉, 매번 문자열을 수동으로 반복해야합니다.

문자열을 확장하여 원하는 색인까지 문자를 반복하는 메소드를 제공 할 수 있습니다

extension String {
    func characterAtIndex(index: Int) -> Character? {
        var cur = 0
        for char in self {
            if cur == index {
                return char
            }
            cur++
        }
        return nil
    }
}

myString.characterAtIndex(0)!

3
이미 문자열을 반복 할 수 있습니다. "foo"의 문자 {println (letter)}
Doobeh

@Doobeh 위의 편집 에서처럼 루프 스루를 의미하고 실제 문자를 반환했습니다.
drewag

좋은! 인덱스를 통해 반복 할 수없는 방법은 재미 있습니다. 스위프트는 비 유적으로 느껴지지만 가장자리는 단단합니다.
Doobeh

나는 사용하여 발견 myString.bridgeToObjectiveC().characterAtIndex(0)또는 (string as NSString ).characterAtIndex(0) 반환 문자의 int 값
markhunte

4
NSStringSwift-native에서 개별 문자에 액세스 하는 데 메소드를 사용 하지 마십시오String . 두 가지 방식은 서로 다른 카운팅 메커니즘을 사용하므로 더 높은 유니 코드 문자로 예기치 않은 결과를 얻을 수 있습니다. 첫 번째 방법은 안전해야합니다 (한 번 Swift의 유니 코드 버그가 처리됨).
Nate Cook

11

참고로, 문자열의 문자 체인 표현에 직접 적용 할 수있는 몇 가지 함수가 있습니다.

var string = "Hello, playground"
let firstCharacter = string.characters.first // returns "H"
let lastCharacter = string.characters.last // returns "d"

결과는 Character 유형이지만 String으로 캐스트 할 수 있습니다.

아니면 이거:

let reversedString = String(string.characters.reverse())
// returns "dnuorgyalp ,olleH" 

:-)


11

스위프트 4

String(Array(stringToIndex)[index]) 

이 문제를 한 번 해결하는 가장 좋은 방법 일 것입니다. 문자열을 먼저 배열로 캐스트 한 다음 결과를 다시 문자열로 캐스트하려고합니다. 그렇지 않으면 문자열 대신 문자가 반환됩니다.

예제 String(Array("HelloThere")[1])는 "e"를 문자열로 반환합니다.

(Array("HelloThere")[1] "e"를 문자로 반환합니다.

Swift는 문자열을 배열처럼 색인화 할 수 없지만 작업을 수행 할 수 있습니다.


1
전체 문자열 내용을 다른 메모리 위치에 복제하는 것은 특히 큰 문자열의 경우 성능이 저하됩니다. 직접 메모리 액세스와 같은 간단한 작업을 위해 추가 메모리 할당이 필요하지 않습니다.
Cristik

7

내 매우 간단한 해결책 :

스위프트 4.1 :

let myString = "Test string"
let index = 0
let firstCharacter = myString[String.Index(encodedOffset: index)]

스위프트 5.1 :

let firstCharacter = myString[String.Index.init(utf16Offset: index, in: myString)]

스위프트 4.1에서 작동
leanne

간단한 솔루션 현재 : 스위프트 5 예와
OhadM

@Linh Dao encodeOffset을 사용하지 마십시오. encodeOffset는 더 이상 사용되지 않습니다. 가장 일반적인 사용법이 올바르지 않아 encodeOffset이 더 이상 사용되지 않습니다.
Leo Dabus

@OhadM가 가장 단순하다고해서 그것이 정확하거나 적어도 예상대로 작동하지 않는다는 것을 의미하지는 않습니다.let flags = "🇺🇸🇧🇷" flags[String.Index(utf16Offset: 4, in: flags)] // "🇧🇷"
Leo Dabus

1
@OhadM 내 의견은 단지 경고였습니다. 예상대로 작동한다고 생각되면 자유롭게 사용하십시오.
Leo Dabus

6

String을 Array로 변환하여 아래와 같이 아래 첨자를 사용하여 특정 색인으로 가져올 수 있습니다.

var str = "Hello"
let s = Array(str)[2]
print(s)

1
이 솔루션을 사용하면 내용이 중복되어 메모리 및 CPU 측면에서 성능이 떨어집니다.
Cristik

5

방금 같은 문제가있었습니다. 간단히 이렇게하십시오 :

var aString: String = "test"
var aChar:unichar = (aString as NSString).characterAtIndex(0)

많은 이모티콘 및 다른 문자에서 실제로 "문자"를 두 번 이상 사용하는 경우에는 실패합니다 NSString.
rmaddy

5

스위프트 3

첨자 구문을 사용하여 특정 문자열 인덱스에서 문자에 액세스 할 수 있습니다.

let greeting = "Guten Tag!"
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index] // a

방문 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html을 하십시오.

또는 Swift 4 에서 문자열 확장을 할 수 있습니다

extension String {
    func getCharAtIndex(_ index: Int) -> Character {
        return self[self.index(self.startIndex, offsetBy: index)]
    }
}

용법:

let foo = "ABC123"
foo.getCharAtIndex(2) //C

3

내 솔루션은 한 줄에 있는데, cadena가 문자열이고 4가 원하는 n 번째 위치라고 가정합니다.

let character = cadena[advance(cadena.startIndex, 4)]

간단합니다 ... Swift에 향후 버전의 하위 문자열에 대한 더 많은 내용이 포함될 것이라고 생각합니다.


1
var charAtIndex = string[advance(string.startIndex, 10)]Sulthan의 답변 과 동일하지 않습니까?
Martin R

예, Sulthan 's와 같은 다른 예제와 동일한 솔루션입니다. 중복해서 죄송합니다. :) 두 사람이 같은 방식으로 쉽게 찾을 수 있습니다.
Julio César Fernández Muñoz

3

스위프트 3 : 다른 솔루션 (운동장에서 테스트)

extension String {
    func substr(_ start:Int, length:Int=0) -> String? {
        guard start > -1 else {
            return nil
        }

        let count = self.characters.count - 1

        guard start <= count else {
            return nil
        }

        let startOffset = max(0, start)
        let endOffset = length > 0 ? min(count, startOffset + length - 1) : count

        return self[self.index(self.startIndex, offsetBy: startOffset)...self.index(self.startIndex, offsetBy: endOffset)]
    }
}

용법:

let txt = "12345"

txt.substr(-1) //nil
txt.substr(0) //"12345"
txt.substr(0, length: 0) //"12345"
txt.substr(1) //"2345"
txt.substr(2) //"345"
txt.substr(3) //"45"
txt.substr(4) //"5"
txt.substr(6) //nil
txt.substr(0, length: 1) //"1"
txt.substr(1, length: 1) //"2"
txt.substr(2, length: 1) //"3"
txt.substr(3, length: 1) //"4"
txt.substr(3, length: 2) //"45"
txt.substr(3, length: 3) //"45"
txt.substr(4, length: 1) //"5"
txt.substr(4, length: 2) //"5"
txt.substr(5, length: 1) //nil
txt.substr(5, length: -1) //nil
txt.substr(-1, length: -1) //nil

2

swift 2.0 subString 업데이트

public extension String {
    public subscript (i: Int) -> String {
        return self.substringWithRange(self.startIndex..<self.startIndex.advancedBy(i + 1))
    }

    public subscript (r: Range<Int>) -> String {
        get {
            return self.substringWithRange(self.startIndex.advancedBy(r.startIndex)..<self.startIndex.advancedBy(r.endIndex))
        }
    }

}

2

첫 번째 캐릭터를 얻는 빠른 답변은 다음과 같습니다.

let firstCharacter = aString[aString.startIndex]

다음보다 훨씬 우아하고 성능이 좋습니다.

let firstCharacter = Array(aString.characters).first

그러나 .. 문자열로 조작하고 더 많은 작업을 수행하려는 경우 확장을 만들 수 있다고 생각할 수 있습니다.이 방법을 사용하는 확장이 하나 있습니다. 여기에 이미 게시 된 것과 매우 유사합니다.

extension String {
var length : Int {
    return self.characters.count
}

subscript(integerIndex: Int) -> Character {
    let index = startIndex.advancedBy(integerIndex)
    return self[index]
}

subscript(integerRange: Range<Int>) -> String {
    let start = startIndex.advancedBy(integerRange.startIndex)
    let end = startIndex.advancedBy(integerRange.endIndex)
    let range = start..<end
    return self[range]
}

}

그러나 그것은 끔찍한 아이디어입니다!

아래 확장은 끔찍하게 비효율적입니다. 문자열이 정수로 액세스 될 때마다 시작 색인을 진행시키는 O (n) 함수가 실행됩니다. 다른 선형 루프 내에서 선형 루프를 실행하면 실수로 for for loop가 O (n2)임을 의미합니다. 스트링 길이가 길어질수록이 루프가 걸리는 시간은 2 차적으로 증가합니다.

대신 문자의 문자열 컬렉션을 사용할 수 있습니다.


2

스위프트 3

extension String {

    public func charAt(_ i: Int) -> Character {
        return self[self.characters.index(self.startIndex, offsetBy: i)]
    }

    public subscript (i: Int) -> String {
        return String(self.charAt(i) as Character)
    }

    public subscript (r: Range<Int>) -> String {
        return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
    }

    public subscript (r: CountableClosedRange<Int>) -> String {
        return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
    }

}

용법

let str = "Hello World"
let sub = str[0...4]

유용한 프로그래밍 팁과 요령


2

첨자 가져 오기 및 설정 (문자열 및 첨자 열)-Swift 4.2

스위프트 4.2, Xcode 10

나는 @alecarlson 의 답변에서 내 대답을 기반으로했습니다 . 유일한 큰 차이점은 a Substring또는 Stringreturn (및 경우에 따라 single Character)을 얻을 수 있다는 것입니다. 당신은 또한 수 getset첨자. 마지막으로 내 것이 @alecarlson 의 답변 보다 약간 성 가시고 길기 때문에 소스 파일에 넣는 것이 좋습니다.


신장:

public extension String {
    public subscript (i: Int) -> Character {
        get {
            return self[index(startIndex, offsetBy: i)]
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
    public subscript (bounds: CountableRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ..< end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeThrough<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ... end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ..< end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }

    public subscript (i: Int) -> String {
        get {
            return "\(self[index(startIndex, offsetBy: i)])"
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            self.replaceSubrange(n...n, with: "\(c)")
        }
    }
    public subscript (bounds: CountableRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ..< end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeThrough<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ... end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ..< end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }

    public subscript (i: Int) -> Substring {
        get {
            return Substring("\(self[index(startIndex, offsetBy: i)])")
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
}
public extension Substring {
    public subscript (i: Int) -> Character {
        get {
            return self[index(startIndex, offsetBy: i)]
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }

    }
    public subscript (bounds: CountableRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ..< end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: PartialRangeThrough<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ... end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ..< end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }
    public subscript (i: Int) -> String {
        get {
            return "\(self[index(startIndex, offsetBy: i)])"
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
    public subscript (bounds: CountableRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ..< end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeThrough<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ... end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ..< end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }

    public subscript (i: Int) -> Substring {
        get {
            return Substring("\(self[index(startIndex, offsetBy: i)])")
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
}

불필요하게 startIndex에서 두 인덱스 (시작 및 끝)를 오프셋합니다. range.count를 사용하여 종료 인덱스를 오프셋하고 시작 인덱스를 오프셋 할 수 있습니다
Leo Dabus

2

스위프트 4.2

이 답변은 하나의 확장으로 확장 String되고 모든 Subsequences( Substring) 이기 때문에 이상적입니다

public extension StringProtocol {

    public subscript (i: Int) -> Element {
        return self[index(startIndex, offsetBy: i)]
    }

    public subscript (bounds: CountableClosedRange<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[start...end]
    }

    public subscript (bounds: CountableRange<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[start..<end]
    }

    public subscript (bounds: PartialRangeUpTo<Int>) -> SubSequence {
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[startIndex..<end]
    }

    public subscript (bounds: PartialRangeThrough<Int>) -> SubSequence {
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[startIndex...end]
    }

    public subscript (bounds: CountablePartialRangeFrom<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        return self[start..<endIndex]
    }
}

용법

var str = "Hello, playground"

print(str[5...][...5][0])
// Prints ","

불필요하게에서 두 인덱스 ( startend)를 오프셋 합니다 startIndex. 당신은 단순히 오프셋 수 endrange.count를 사용하여 인덱스를 오프셋 start인덱스
레오 버스들이시길

2

현재는 첨자 (_ :)를 사용할 수 없습니다. 뿐만 아니라 우리는 이것을 할 수 없습니다

str[0] 

"String.Index"를 제공해야하지만 어떻게 이런 식으로 우리 고유의 인덱스 번호를 부여 할 수 있습니까?

string[str.index(str.startIndex, offsetBy: 0)]

코드 전용 답변을 게시하는 대신 답변이 문제를 해결하는 방법을 설명하여 답변을 편집하고 컨텍스트를 추가하십시오. 검토에서
페드 람 Parsian

왜 불필요한 오프셋을 수행합니까? 왜 간단하지 string[string.startIndex]않습니까? BTW, 두 개의 다른 변수 이름을 사용했기 때문에 코드가 올바르게 동작 / 컴파일되지 않았습니다.
Cristik

2

스위프트 4.2 이상

Stringindices속성을 사용한 범위 및 부분 범위 첨자

@LeoDabus nice answer의 변형으로 , 우리는 후자에 대한 커스텀 첨자를 구현할 때 ( 특수 범위 및 부분 범위 DefaultIndices에 따라) indices속성 으로 대체 할 수 있도록 추가 확장을 추가 할 수 있습니다 .StringInt

extension DefaultIndices {
    subscript(at: Int) -> Elements.Index { index(startIndex, offsetBy: at) }
}

// Moving the index(_:offsetBy:) to an extension yields slightly
// briefer implementations for these String extensions.
extension String {
    subscript(range: Range<Int>) -> SubSequence {
        let start = indices[range.lowerBound]
        return self[start..<indices[start...][range.count]]
    }
    subscript(range: ClosedRange<Int>) -> SubSequence {
        let start = indices[range.lowerBound]
        return self[start...indices[start...][range.count]]
    }
    subscript(range: PartialRangeFrom<Int>) -> SubSequence {
        self[indices[range.lowerBound]...]
    }
    subscript(range: PartialRangeThrough<Int>) -> SubSequence {
        self[...indices[range.upperBound]]
    }
    subscript(range: PartialRangeUpTo<Int>) -> SubSequence {
        self[..<indices[range.upperBound]]
    }
}

let str = "foo bar baz bax"
print(str[4..<6]) // "ba"
print(str[4...6]) // "bar"
print(str[4...])  // "bar baz bax"
print(str[...6])  // "foo bar"
print(str[..<6])  // "foo ba"

아래 첨자 indices대신 다른 속성으로 속성 을 사용하는 방향으로 나를 가리켜 준 @LeoDabus에게 감사드립니다 String!


1
유일한 단점은 CountableClosedRange가 startIndex에서 두 인덱스를 오프셋한다는 것입니다.
Leo

1
@LeoDabus 알겠습니다. 예, 대부분 리눅스이지만 요즘 많이 스위프트는 아닙니다 .// swiftenv내가 할 때 사용 하지만 4.2로 업데이트 될 것 같습니다.
dfri

1
현대 Swift로이 답변을 업데이트 해 주셔서 감사합니다.
dfri

1
@LeoDabus 잘 했어! 나중에 세부 사항을 살펴 봐야하지만 주문 / 계산 가능한 세트 유형 중 일부를 Foundation으로 대체해야한다는 것을 결코 기억하지 못합니다.
dfri

1
고마워 친구!!!
Leo Dabus

2

스위프트 5.1.3 :

문자열 확장을 추가하십시오.

extension String {

 func stringAt(_ i: Int) -> String { 
   return String(Array(self)[i]) 
 } 

 func charAt(_ i: Int) -> Character { 
  return Array(self)[i] 
 } 
}

let str = "Teja Kumar"
let str1: String = str.stringAt(2)  //"j"
let str2: Character = str.charAt(5)  //"k"

1
이 속성을 호출하여 단일 문자를 추출 할 때마다 전체 문자열을 문자 배열로 변환합니다.
Leo Dabus

1

스위프트 String타입은characterAtIndex유니 코드 문자열을 인코딩 할 수있는 여러 가지 방법이 있기 때문에 메소드를 . UTF8, UTF16 또는 다른 것을 사용하고 있습니까?

및 속성 CodeUnit을 검색 하여 컬렉션에 액세스 할 수 있습니다 . 검색을 통해 컬렉션에 액세스 할 수도 있습니다 .String.utf8String.utf16UnicodeScalarString.unicodeScalars속성 .

NSString구현 의 정신으로 unichar유형을 반환합니다 .

extension String
{
    func characterAtIndex(index:Int) -> unichar
    {
        return self.utf16[index]
    }

    // Allows us to use String[index] notation
    subscript(index:Int) -> unichar
    {
        return characterAtIndex(index)
    }
}

let text = "Hello Swift!"
let firstChar = text[0]

16 비트보다 더 많은 스토리지가 필요한 문자는 실패합니다. 기본적으로 U + FFFF 이상의 유니 코드 문자입니다.
rmaddy

1

주제를 제공하고 신속한 첨자 가능성을 보여주기 위해 다음은 작은 문자열 "substring-toolbox"첨자 기반입니다.

이 메소드는 안전하며 문자열 인덱스를 넘지 않습니다.

extension String {
    // string[i] -> one string char
    subscript(pos: Int) -> String { return String(Array(self)[min(self.length-1,max(0,pos))]) }

    // string[pos,len] -> substring from pos for len chars on the left
    subscript(pos: Int, len: Int) -> String { return self[pos, len, .pos_len, .left2right] }

    // string[pos, len, .right2left] -> substring from pos for len chars on the right
    subscript(pos: Int, len: Int, way: Way) -> String { return self[pos, len, .pos_len, way] }

    // string[range] -> substring form start pos on the left to end pos on the right
    subscript(range: Range<Int>) -> String { return self[range.startIndex, range.endIndex, .start_end, .left2right] }

    // string[range, .right2left] -> substring start pos on the right to end pos on the left
    subscript(range: Range<Int>, way: Way) -> String { return self[range.startIndex, range.endIndex, .start_end, way] }

    var length: Int { return countElements(self) }
    enum Mode { case pos_len, start_end }
    enum Way { case left2right, right2left }
    subscript(var val1: Int, var val2: Int, mode: Mode, way: Way) -> String {
        if mode == .start_end {
            if val1 > val2 { let val=val1 ; val1=val2 ; val2=val }
            val2 = val2-val1
        }
        if way == .left2right {
            val1 = min(self.length-1, max(0,val1))
            val2 = min(self.length-val1, max(1,val2))
        } else {
            let val1_ = val1
            val1 = min(self.length-1, max(0, self.length-val1_-val2 ))
            val2 = max(1, (self.length-1-val1_)-(val1-1) )
        }
        return self.bridgeToObjectiveC().substringWithRange(NSMakeRange(val1, val2))

        //-- Alternative code without bridge --
        //var range: Range<Int> = pos...(pos+len-1)
        //var start = advance(startIndex, range.startIndex)
        //var end = advance(startIndex, range.endIndex)
        //return self.substringWithRange(Range(start: start, end: end))
    }
}


println("0123456789"[3]) // return "3"

println("0123456789"[3,2]) // return "34"

println("0123456789"[3,2,.right2left]) // return "56"

println("0123456789"[5,10,.pos_len,.left2right]) // return "56789"

println("0123456789"[8,120,.pos_len,.right2left]) // return "01"

println("0123456789"[120,120,.pos_len,.left2right]) // return "9"

println("0123456789"[0...4]) // return "01234"

println("0123456789"[0..4]) // return "0123"

println("0123456789"[0...4,.right2left]) // return "56789"

println("0123456789"[4...0,.right2left]) // return "678" << because ??? range can wear endIndex at 0 ???

1

음의 인덱스를 사용할 수있는 파이썬과 같은 솔루션,

var str = "Hello world!"
str[-1]        // "!"

될 수 있습니다 :

extension String {
    subscript (var index:Int)->Character{
        get {
            let n = distance(self.startIndex, self.endIndex)
            index %= n
            if index < 0 { index += n }
            return self[advance(startIndex, index)]
        }
    }
}

그건 그렇고, 파이썬의 조각 표기법 을 바꾸는 것이 가치가있을 수 있습니다.


Swift 4 용으로 컴파일되는 것을 작성 하시겠습니까? 마지막 반환 ... 줄이 advance () 함수가 작동하지 않는 것 같습니다.
C0D3

1

다음과 같이 문자열을 문자 배열로 변환 할 수도 있습니다.

let text = "My Text"
let index = 2
let charSequence = text.unicodeScalars.map{ Character($0) }
let char = charSequence[index]

이것은 일정한 시간에 지정된 인덱스에서 char을 얻는 방법입니다.

아래 예제는 일정한 시간에 실행되지 않지만 선형 시간이 필요합니다. 따라서 인덱스로 문자열을 많이 검색하는 경우 위의 방법을 사용하십시오.

let char = text[text.startIndex.advancedBy(index)]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.