검색결과 리스트
slicing strings에 해당되는 글 1건
- 2015.06.23 [swift] 문자열 Indexing과 Slicing
글
[swift] 문자열 Indexing과 Slicing
Indexing and Slicing Strings
Swift string의 Indexing과 Slicing 대해서 알아보겠습니다.
string은 화면에 보여지는 문자들의 순서집합이라고 생각하는 것이 일반적입니다.
하지만 하나의 문자로 보일지라도 메모리 상에서는 다중 혹은 가변길이의 유니코드값으로 표현되는 경우도 있습니다.
유니코드 문자열
예를 들어 hat emoji (🎩)는 문자 a와 같은 문자보다 인코딩에 더 많은 비트가 필요로합니다.
Swift의 String 타입은 이러한 세부사항들을 처리해줍니다. string을 이루는 각 문자는 (메모리에서 차지하는 길이와는 상관없이)
사용자가 인식하는 유니코드 문자를 표현합니다. 이런 추상화 때문에 정수를 사용해서 string의 인덱스를 표현하는 것이 적합하지
않을수 있습니다.
대신 표준라이브러리는 string에서의 위치를 표현하기에 적합한 String.Index를 제공합니다.
문자열 카운팅
다음 문자열은 가변길이의 유니코드 문자들로 구성되어 있습니다.
var str = "Héllo, 🇺🇸laygr😮und!"
// str의 유니코드 문자의 개수: 18
str.characters.count // swift2.0
count(str) // swift1.2
// str의 UTF-16코드 포인트의 개수: 22
str.utf16.count // swift2.0
count(str.utf16) // swift1.2
깃발 (🇺🇸) 문자는 사실 2개의 유니코드 스칼라값이 결합되어 구성되지만 Swift는 1개의 문자로 카운팅합니다.
이런 특성이 폼 유효성 검사, 커서 포지셔닝, 텍스트 wrapping 구현을 더 쉽게합니다.
문자열 카운팅, 인덱싱, 슬라이싱은 모두 메모리가 아닌 사용자가 인식하는 문자 인덱스를 기반으로 하고있습니다.
문자열 slicing
string을 index하고 slice하는데 사용하는 Range 값을 생성해보겠습니다.
let badRange = 4..<12 // Range<Int>를 생성합니다.
str[badRange] // error: 'subscript' is unavailable: cannot subscript String with range of Int
위 코드는 정수형을 string의 인덱스로 사용할수 없다는 컴파일 에러를 발생시킵니다.
대신 다음과 같이 String.Index 객체를 사용할 수 있습니다.
let range = advance(str.startIndex, 4)..<advance(str.startIndex, 12)
string은 startIndex 와 endIndex 속성을 갖습니다.
string의 successor(), predecessor() 함수(swift2.0에서 지원)는 인덱스를 증가 또는 감소시킵니다.
advance() 함수를 사용하여 파라미터의 값만큼 offset를 이동할수 있으며, advance()함수는 인자로 전달받은 offset 만큼 successor(),predecessor()를 호출합니다.
String.Index 타입은 유니코드를 인식할수 있어서 advance()함수가 항상 string index를 적절하게 이동시킬 수 있습니다.
advance() 함수는 인자로 받은 index 타입과 동일한 타입의 값을 반환하기 때문에 ..< range 연산자는 그 타입에 해당하는 range를
생성할수 있습니다.
advance() 함수를 사용하여 string의 특정 index의 문자를 조회해보겠습니다.
str[advance(str.startIndex, 7)] // 🇺🇸를 반환한다.
str[range.startIndex] // o를 반환한다.
str[range.endIndex] // 😮를 반환한다.
str[range] // o, 🇺🇸laygr를 반환한다.
advance() 함수
또 다른 버전의 advance()함수를 사용해서 메시지를 10자로 제한하는 기능을 구현해보겠습니다.
let messageCharacterLimit = 10
let range = advance(str.startIndex, messageCharacterLimit , str.endIndex)..<advance(str.endIndex, 0)
let result = str.substringWithRange(range)
if result.isEmpty {
print("empty result")
}
// "ygr😮und!"를 출력합니다.
advance()함수는 startIndex, offset 외에 세번째 파라미터로 endIndex를 전달하면 offset이 endIndex를 초과하는 경우
end.Index를 반환해줍니다. 세번째 인자는 일종의 상한값으로 동작합니다.
'Swift' 카테고리의 다른 글
| [swift2] 타입의 텍스트적인 표현 커스터마이징하기 (0) | 2015.07.01 |
|---|---|
| [swift2] Xcode7 beta2 Swift 언어 변경사항 (0) | 2015.06.24 |
| [swift] 문자열 Indexing과 Slicing (0) | 2015.06.23 |
| [swift] Map, Filter, Reduce (0) | 2015.06.22 |
| [swift2] New in Swift2.0 (0) | 2015.06.19 |
| [swift] Apple Swift Blog (0) | 2015.06.10 |