2014년 11월 5일 수요일

Swift String의 split과 join

Swift의 String은 split이나 join 같은 기능을 제공하지 않는다. 이게 뭐 대단한 사실은 아니지만, Python에서 개인적으로 문자열의 split이나 문자열 배열 join 기능은 굉장히 유용하고 자주 사용하는 기능이었기에 Swift에도 있었으면 했다.

(왠지 이번에도 Python 중독자 이야기가 되는 것 같다 -_-)

Split

Split 기능은 Swift의 String에서는 앞서 이야기 한 대로 제공되지 않는다. 그러나, Swift String 에서 제공 안한다는 의미일 뿐이다. 즉, NSString 에서는 제공된다. 이제는 아예 NSString으로 캐스팅을 하지 않아도 NSString의 메소드를 마음껏 이용 할 수 있으니 그냥 Swift String의 기능이라고 봐도 무방하려나.

Python의 split 기능은 문자열을 특정 문자열을 기준으로 배열로 쪼게어 버리는 기능이다. NSString에서는 componentsSeparatedByString 혹은 componentsSeparatedByCharactersInSet 이라는 두 가지 메소드를 이용해 비슷하게 사용이 가능하다.

이 기능을 (마치 파이썬 스럽게 만들기 위해) String을 확장(Extension)해서 구현해보자.
extension String {
    func arrayBySpliting(splitter: String? = nil) -> [String] {
        if let s = splitter {
            return self.componentsSeparatedByString(s)
        } else {
            return self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
        }
    }
}
그냥 메소드 네이밍을 완전 동일하게 split으로 지어 줄 수도 있었겠지만 이 코드는 Swift이다. Objective-C와의 연계도 생각해야 하니 네이밍 룰을 어느정도 따랐다고 볼 수 있다. 이 코드의 사용 예는 아래와 같다.
let str1 = "1,2,3,4,5"
let arr1 = str.arrayBySpliting(splitter: ",")
// arr1 = [ "1", "2", "3", "4", "5" ]

let str2 = "this is test"
let arr2 = str2.arrayBySpliting()
// arr2 = [ "this", "is", "test" ]
파이썬의 split()은 별도의 구분자 문자열을 넣지 않으면 공백 등의 Whitespace를 구분자로 사용한다. 그것도 동일하게 구현되어 있는 상태이다.

뭐 굳이 extension으로 구현하지 않아도 관계는 없다. 필요하다면 내부의 코드만 사용해도 상관은 없다. 개인 자유다. :-)

Join

이제 반대로 join에 대해 살펴보자. 파이썬의 join은 문자열로 구성된 배열을 하나의 문자열로 합치는 기능이다. 비슷하게 합칠 때 구분자를 문자열로 대입 할 수 있다.

그런데, Swift Array나 NSArray는 이런 기능을 제공하지 않는 것 같다. 그래서 그냥 아예 만들어버렸다. 아래는 예제 코드이다.
extension Array {
    func stringByJoining(separator: String) -> String {
        var result = ""
        for (idx, item) in enumerate(self) {
            result += "\(item)"
            if idx < self.count - 1 {
                result += seperator
            }
        }
        return result
    }
}
역시나 전통적인 네이밍 룰을 따라서 stringByJoining 이라는 메소드로 확장을 해서 구현하였다. 위의 split 예제 코드에서 바로 이어지는 사용법은 아래와 같은 식이다.
println(arr1.stringByJoining(separator: "/")
// "1/2/3/4/5"

println(arr2.stringByJoining(separator: ".")
// "this.is.test"
말 그대로 그냥 배열의 문자열을 하나로 합쳐버리는데 그 사이에 원하는 문자열을 끼워 넣을 수 있다.

아래 링크는 위 내용이 그대로 구현되어 있는 개인라이브러리 소스코드 링크이다. 이 외의 기능들도 구현되어 있으니 참고하자.
https://github.com/seorenn/SRChoco/blob/master/SRChoco/Utilities/StringExtensions.swift
https://github.com/seorenn/SRChoco/blob/master/SRChoco/Utilities/ArrayExtensions.swift

댓글 없음 :