Search
Duplicate

String.Index()

생성일
2023/11/30 08:09
태그
Grammar

 String.Index()

String은 Character의 집합이다.
Character는 유니코드 문자로 이루어지는데 유니코드의 크기가 다양하기 때문에 정수로 index를 구분하기 애매하다.
따라서 String은 Random Access를 채택하는 대신 BidirectionalCollection 프로토콜을 채택하여 순차 탐색하도록 구현되었다.
이런 이유로 String은 Subscript 대신 String.Index 라는 구조체로 String의 인덱스를 관리하게 되었다.

 String.Index → Int

String의 distance(from:to:)를 이용하면 Int 인덱스를 구할 수 있다.
→ from과 to의 거리를 리턴하는 메서드
let distance = string.distance(from: string.startIndex, to: 변환할 String.Index)
Swift
복사
이렇게 startIndex와 원하는 String.Index를 비교하면 Int 값을 얻을 수 있다.

 문자열의 첫 글자 구하기

 startIndex

startIndex를 이용하면 문자열의 시작 인덱스를 알 수 있다.
let string: String = "abcdefg" let first = string.startIndex print(string[first]) // a
Swift
복사

 prefix(_:)

prefix 메서드를 이용하면 0~n번째까지의 Substring을 구할 수 있다.
let first = string.prefix(2) print(first) // ab
Swift
복사
String에서 prefix 메서드는 O(n)의 시간복잡도를 가진다.
이것도 BidirectionalCollection을 채택하고 있기 때문.

 문자열의 n 번째 글자 구하기

 index(after:)

문자열의 n번째 글자는 index(after:)을 이용해 쉽게 구할 수 있다.
index(after:)는 매개변수 String.Index를 받고 전달받은 String.Index의 다음 String.Index를 구할 수 있다.
예를들어, startIndex의 다음 인덱스는 두번째 인덱스이다.
let first = string.startIndex let second = string.index(after: first) print(string[second]) // b
Swift
복사

 String.Index(encodedOffset:)

String.Index를 생성할 때 encodedOffset 프로퍼티를 설정하면 n번째 String.Index를 생성할 수 있다.
print(string[String.Index(encodedOffset: 3)]) // d
Swift
복사
3을 encodedOffset로 설정해서 생성하면 네 번째 문자인 d가 출력된다.
인덱스는 0부터 시작이니 3은 네 번째 문자가 된다.

 index(_:offsetBy:)

offsetBy에 정수 n을 입력하면 Index에서 n만큼 이동한 String.Index를 구할 수 있다.
let start = string.startIndex print(string[string.index(start, offsetBy: 0]) // a print(string[string.index(start, offsetBy: 2]) // c
Swift
복사
offsetBy에는 음수도 전달할 수 있다.
let index = String.Index(encodedOffset: 3) // d print(string[string.index(index, offsetBy: -2)]) // b
Swift
복사
3에서 -2를 한 1번째 글자인 b가 출력된다.
주의할 점은 string 범위를 벗어날 경우, 런타임 에러가 발생한다.

 문자열의 마지막 문자 구하기

 endIndex

String.Index 타입인 endIndex는 String의 마지막 인덱스를 가리킨다.
이때 주의할 점은 마지막 빈 공간(like C언어의 \0)을 가리킨다는 것이다.
print(string[string.endIndex]) // error
Swift
복사
그래서 endIndex에 접근하면 런타임 에러가 발생하게 된다.
이럴 땐 index(before:)을 사용하면 된다.
print(string[string.index(before: string.endIndex)]) // g
Swift
복사
→ endIndex의 바로 이전 인덱스를 출력하니 마지막 글자인 g가 출력되었다.

 suffix(_:)

suffix(_:)를 이용하면 뒤에서부터 n개의 Substring을 구할 수 있다.
print(string.suffix(3)) // efg
Swift
복사

 특정 문자의 인덱스 구하기

특정 문자가 몇 번째 인덱스에 있는지 확일할 때는 firstIndex(of:), lastIndex(of:), index(of:) 를 이용하면 됩니다.

 firstIndex(of:)

firstIndex(of:) 는 매개변수로 전달한 문자가 처음 나오는 인덱스를 리턴한다.
만약 입력한 문자가 없다면 nil이 출력된다.
그리고 값을 비교할 수 있어야 하기 때문에 element는 Equatable 해야한다.
print(string.firstIndex(of: "d")) // d의 String.Index print(string.firstIndex(of: "h")) // nil
Swift
복사
여기서 String.Index → Int 방법으로 d의 String.Index를 변환해보면
let distance = string.distance(from: string.startIndex, to: string.firstIndex(of: "d")!) print(distance) // 3
Swift
복사
firstIndex는 문자가 가장 먼저 나오는 String.Index를 반환하기 때문에 일치하는 문자가 여러 개면 가장 먼저 나오는 글자의 인덱스를 리턴한다.
let string = "aaaaa" let distance = string.distance(from: string.startIndex, to: string.firstIndex(of: "a")!) print(distance) //0
Swift
복사
a가 가장 먼저 나오는 위치는 0이기 때문에 0이 출력된다.

 lastIndex(of:)

lastIndex는 마지막으로 나오는 String.Index를 반환한다.
일치하는 문자가 없다면 nil을 반환한다.
let string = "aaaaa" let distance = string.distance(from: string.startIndex, to: string.lastIndex(of: "a")!) print(distance) // 4
Swift
복사

 reference