항상 Python으로 알고리즘 문제들을 풀다가, 최근에 Swift로 문제를 풀기 시작했습니다.
기초 문법들을 공부하면서 알게되는 내용들을 하나 씩 포스팅 할 예정입니다.
이번 포스팅은 문자열을 구분짓는 메서드인 components()와 split()에 대해 알아보려고 합니다!
프로그래머스 레벨 0 문제들을 풀면서 기초 문법들을 익히고 있는데,
문자열 구분 문제들에서 components()를 쓰는 경우와 split()을 쓰는 경우가 각각 있더라구요.
그래서 애플 공식 문서와 Xcode에서 Jump to Definition을 통해 알아보았습니다.
공식 문서에는 다음과 같이 설명되어 있습니다.
구분자
입니다.String 타입의 separator
를 받아서 [String] 타입을 반환
하네요.
즉, 현재 문자열을 구분자를 기준으로 문자열을 분할하고, 결과를 배열로 반환
입니다.
[String] 으로 반환한 다는 것이 특징입니다.
let str = "Hi, I'm an iOS Developer."
let sep = " "
str.components(separatedBy: sep)
// ["Hi", "I\'m", "an", "iOS", "Developer."]
기본적으로 다음과 같이 실행됩니다.
하지만 components()만의 특징은 따로 있습니다!
바로, 연속된 구분자나 문자열의 시작과 끝에 있는 구분자는 빈 문자열("")을 포함
한 배열이 반환된다는 것입니다.
let str = "Hello, HHorld! HahaHaHH"
let sep = "H"
str.components(separatedBy: sep)
// ["", "ello, ", "", "orld! ", "aha", "a", "", ""]
이렇게 말이죠.
split()은 다음과 같이 설명되어 있네요.
눈에 띄는 점은 separator의 타입이 Self.Element
라는 것과 반환 타입이 [Self.SubSequence]
라는 것입니다.
split()은 문자열 뿐만 아니라 다른 자료형(Array, Set 등)에서도 사용
할 수 있도록 유연하게 만들어졌다고 합니다.
또한, 반환 형태가 SubSequence
이기 때문에 String을 분할해서 String을 반환하고 싶다면 map()을 써주어야 하죠.
구분자
입니다.최대 몇 번 분할하는지 결정하는 값
입니다.빈 요소를 반환하는지 결정하는 값
입니다.components()보다 훨씬 이후에 나와서 그런지, 기능이 추가되었네요.
문자열에선 omittingEmptySubsequences만 false로 해주면 components()와 같은 결과가 반환됩니다.
그럼 직접 한 번 해볼까요?
let str = "Hello, HHorld! HahaHaHH"
let sep = "H"
str.components(separatedBy: sep)
// ["ello, ", "orld! ", "aha", "a"]
빈 문자열은 포함하지 않고 반환됩니다.
str.split(separator: sep, maxSplits: 3)
// ["ello, ", "orld! ", "aha", "aHH"]
maxSplits를 3로 설정한 경우 다음과 같이 반환됩니다.
결과가 헷갈릴 수도 있습니다만, 과정을 살펴보면 다음과 같습니다.
첫 번째 H를 만난 후 분할: "ello, "와 "Horld! HahaHaHH" => 분할 1번 ->
두 번째 H를 만난 후 분할: "orld! "와 "HahaHaHH" => 분할 2번
세 번째 H를 만난 후 분할: "aha"와 "aHH" => 분할 3번
이렇게 3번의 분할이 일어나는 것입니다.
str.split(separator: sep, omittingEmptySubsequences: false)
// ["", "ello, ", "", "orld! ", "aha", "a", "", ""]
components()를 사용했을 때와 같은 결과가 반환됩니다.
주의: 결과 자체는 같지만 SubSequence로 타입은 다르다는 것.
let arr = [1, 2, 3, 4, 5, 3, 6, 7, 3, 8, 3]
let sep = 3
arr.split(separator: sep)
// [ArraySlice([1, 2]), ArraySlice([4, 5]), ArraySlice([6, 7]), ArraySlice([8])]
잘 되네요!
추가로, split()의 공식 문서에 다음과 같은 내용이 있길래 가져왔습니다.
기존의 separator가 whereSeparator로 이동하면서, 클로저를 통해 구분자의 조건을 설정할 수 있습니다.
반환 형태는 똑같네요.
사용하는 방법은 다음과 같습니다.
공백을 없애주고 싶다면 이렇게 하면 됩니다. 다른 추가 조건이 있으면 그에 맞게 클로저에 구현해주면 되겠죠??
let str = "Hi, I'm an iOS Developer."
str.split(whereSeparator: { $0.isWhitespace })
// ["Hi", "I\'m", "an", "iOS", "Developer."]
이렇게 문자열 구분에서 자주 쓰이는 components()와 split() 두 개를 비교해보았습니다!!
저도 이번에 공부하면서 두 개의 차이가 무엇인지 명확하게 알게되었습니다.
그럼 다시 프로그래머스 풀러 가야겠습니다....
애플 공식 문서: components()
애플 공식 문서: split()
애플 공식 문서: split() - 클로저