2014년 6월 11일 수요일

Swift - 컬렉션 타입(Collection Types)

컬렉션(Collection) 이라는 것은 하나 이상의 데이터를 보관 할 수 있는 특수한 자료구조를 의미한다. 대체로 리스트나 배열, 그리고 사전 형식이 이 타입에 해당되는데 스위프트(Swift)에도 Array와 Dictionary 타입이 해당한다. 그 외에 집합과 비슷한 Set 타입도 1.2에 추가되었다.

배열(Array)

배열(Array)은 이름처럼 C의 배열과 비슷하지만 리스트 혹은 동적 배열로 봐야한다.
let decimals = [ 10, 20, 30, 40 ]
let names = [ "Chris", "Alex", "Ewa", "Barry", "Daniella" ]
let complexes = [ 10, "str", 20 ]
타입을 강제로 줘서 만들 수도 있다.
// 아래 코드는 Xcode 6 Beta 3 부터는 경고가 뜬기 때문에 사용하지 말것.
let animals: String[] = [ "cow", "dog", "cat" ]

// Beta 3 부터는 Sugar Syntax가 지원된다.
let animals: [String] = [ "cow", "dog", "cat" ]
빈 Array를 만드는 것도 당연히 가능하다. 하지만 타입을 강제해야 한다.
// 역시 Xcode 6 Beta 3 부터는 경고가 뜬다.
var emptyStringArray = String[]()

// Sugar Syntax
var emptyStringArray = [String]()

// 일반적인 Array 인스턴스 생성
var emptyStringArray2 = Array<String>()
개인적으론 []() 이런 순서 표기를 왜 반대로 쓰지라는 생각을 오랫동안 했는데 뭐 그러려니 하자. String을 생성해서 Array화 하느냐 아니면 String 형식의 Array를 만드느냐는 표현의 차이가 오해를 불러오는 것일 뿐이다. 애플에서도 타입 뒤에 대괄호([])를 명기하는 방식이 모호함을 준다는 것을 인식했는지 Xcode 6 Beta 3 부터는 Sugar Syntax 라는 새로운 문법으로 대체하기 시작했다.

Array의 갯수는 count 프로퍼티를 이용해 구할 수 있다.
names.count      // 5
Array의 참조나 변경은 각 아이템 인덱스를 줘서 할 수 있다.
println(names[0])
names[1] = "Christian"
Array의 일부분을 Array 형식으로 가져올 때는 인덱스 대신 Range를 활용한다.
names[1...2]
names[1..<3]
위 코드는 둘 다 1, 2번 인덱스의 아이템으로 구성된 Array를 돌려준다.

​Array의 활용은 이터레이션(Iteration)에서 빛난다.
for name in names {
    println(name)
}
앞서 선언한 names 라는 Array의 각 아이템을 콘솔에 찍는 코드다.

이 외에 Array는 아래와 같은 유용한 메소드와 프로퍼티들을 갖추고 있다:
  • isEmpty: 비어있으면 true가 들어있겠지.
  • append(): 이름 처럼 아이템을 하나 추가하는 메소드. 리스트를 넣어서 한번에 대량으로 추가하는 것도 가능.
  • insert(item, atIndex: index): 특정 인덱스에 아이템을 추가하는 메소드
[관련글] Swift - Array의 세 가지 도구: map, filter, reduce

사전형(Dictionary)

사전이 무엇인지는 다들 알 것이다. 특정 단어의 뜻을 찾아보기 위한 책이다. 프로그래밍 언어에서 사전형은 이렇게 특정 키(단어)에 데이터(뜻)을 매칭시키기 위한 특수한 자료구조이다. 특수하다고는 했지만 굉장히 자주 쓰이니 꼭 알아두자.

사전형도 Array와 비슷하지만 좀 다르기도 하다.
let someDic = [ "name": "Alex", "country": "USA" ]
참조할 때는 Array에서 인덱스를 주는 것과는 다르게 키 이름을 줘야 한다. 여기서는 문자열로 키를 정의했기 때문에 문자열로 키를 넘겨준다.
let name = someDic["name"]
println(someDic["country"])
빈 사전형을 만들 때도 타입을 꼭 명시해 주어야 한다. 아래 코드는 String 타입의 키와 String 타입의 데이터를 가질 수 있는 빈 사전형 인스턴스를 만드는 예이다.
var emptyDic = Dictionary<String, String>()
var emptyDic2 = [String: String]()
미안하다. 사실은 거짓말이다. 꼭 타입 명시 없이 이렇게 간단하게 만드는 방법도 있다.
var emptyDic2 = [:]
근데 그냥 만들기만 할 뿐 이걸 쓰는건 상당히 귀찮을 것이다. 왜냐하면 앞서 생성한 타입 강제형과는 다르게 타입이 정의되지 않았기 때문이다. 대신 위의 코드는 빈 사전형을 만든다기 보다 이미 만들어져 있는 사전형의 데이터를 싹 비울 때 쓰면 유용할거다.

사전형도 이터레이션이 가능하다. 하지만 받게 되는 데이터가 튜플 형식임에 유의하자.
for (key, value) in someDic {
    println("key = \(key), value = \(value)")
}
키만 가져와서 이터레이션 하는 건 .keys 라는 프로퍼티를 활용하면 할 수 있다.
for key in someDic.keys {
    println(key)
}
그 외에 Array와 비슷하게 count 프로퍼티를 이용해 갯수도 알 수 있다. 키와 오브젝트는 페어이기 때문에 한 개로 계산된다는 점에 유의하자.
someDic.count    // 2
[관련글] Swift - 튜플(Tuple)

집합(Set)

Set 타입은 Swift 1.2에 추가된 새로운 컬렉션 타입으로 순서가 없는 고유값(Unique Value)를 보관하기 위한 특수한 배열이라고 볼 수 있다. 물론 Foundation의 NSSet이나 NSMutableSet과 비슷한 형태로 볼 수 있다.

Set 타입에 대한 자세한 내용은 아래 링크를 참고하자:
[관련글] Swift 1.2 - Set 타입

[돌아가기] 스위프트(Swift) 가이드

댓글 5개 :

강철 :

http://swift.leantra.kr/ 그렇고 Sugar Syntax 변경에 대한 부분이
적용이 안되어 있어서 왜 오류가 생기나했네요..(playground에서는 오류 표시도 안나는군요 ㅠ)

그래도 주인장님께서 변경된 부분에 대해 가장 발빠르게 작성을 해두셔서 큰 도움되었습니다.

감사합니다 ^^

강철 :
작성자가 댓글을 삭제했습니다.
강철 :
작성자가 댓글을 삭제했습니다.
강철 :

names[1..3] 수정하면 좋겠네요 :)

Renn Seo :

옛날 문법이 그대로 남아있었네요. 감사합니다. 곧 수정 할게요~~