본문 바로가기

난 iOS개발자/iOS

String을 Subscript로 접근할 수 없는 이유

728x90

Swift의 String은 구조체이며 Character의 모음이다.

즉 Character의 배열인 셈이다.

 

Character는 결합 시 사람이 읽을 수 있는 단일 문자를 생성하는 하나 이상의 유니코드 스칼라 시쿼스이다.

일부 문자에는 2개의 유니코드가 필요할 수 있고, 어떤 이모티콘은 4개의 유니코드가 필요할 수도 있다.

 

결과적으로 문자는 저장할 가변크기의 메로리가 필요하므로 인덱싱이 어렵다.

문자가 4바이트와 같이 고정된 크기의 경우 문자열에서 문자의 위치 i를 찾으려면 문자열의 시작점에서 4 * i 옵셋을 추가하면 된다.

 

그러나 문자가 가변 크기의 경우 해당 문자열의 시작 또는 끝에서 유니코드 스칼라를 반복하여 문자열의 인덱스를 찾아야한다.

 

문자열을 인덱싱하기 위해서는 String.index 를 사용해야 한다.

let name = "Jun"
let index = name.index(name.startIndex, offsetBy:1)
let char = name[index] // u

이 방법을 사용해도 시간복잡도는 O(n)이다.

 

부분 문자열을 얻으려면 Range를 사용해야 한다.

let name = "Neil"

let index1 = name.index(name.startIndex, offsetBy:1)
let index2 = name.index(name.startIndex, offsetBy:3)
let indexRange = index1...index2

let subString = name[indexRange] //eil

 

String효율적으로 사용하기

String은 Collection의 RandomAccessCollection프로토콜을 준수하지 않으므로 O(1)접근이 되지 않는다.

앞 뒤 원소만 참조할 수 잇는 BidirectinoalCollection을 준수한다. 따라서 임의이 거리의 원소를 참조하기 위해서는 그 이전 단계의 원소를 모두 차례대로 거쳐야 한다. 글자 참조의 시간복잡도가 O(n)인 이유다.

 

Swift로 문자열을 다룰 때 다음과 같은 테크닉을 활용해보자.

 

첫번째. 문자열의 길이를 자주 참조한다면, 처음 한 번 구해서 별도의 변수에 저장해 놓자.

두번째. index도 매번 구하지 말고 재활용하는 하여 연산수를 줄이자.

 

세번째. String의 글자들에 임의 접근이 필요하다면 String을 Character의 Array로 바꿔서 사용해보자.

문자열에 빈번한 순회가 필요하다면 String.index보다 Character Array사용이 훨씬 효율적이다.

let str = "Hello, World!"

let arr = Array(str)

print(arr) 
// ["H", "e", "l", "l", "o", ",", " ", "W", "o", "r", "l", "d", "!"]

 

참조: https://medium.com/@banghua.zhao/why-cannot-subscript-string-with-an-int-in-swift-281cfc83402

728x90

'난 iOS개발자 > iOS' 카테고리의 다른 글

NSCache  (0) 2022.05.07
ARC(Auto Reference Counting)  (0) 2022.05.05
Class의 성능을 향상 시키는 방법  (0) 2022.05.03
initialization -3  (0) 2022.04.29
initialization-2  (0) 2022.04.27