The Swift Programming Language - Collection Types（集合型、Array とか Dictionary）をまとめる


[The Swift Programming Language をまとめるトップ](http://qiita.com/kiyotaman/items/052f82e9f93590b79c64)

## Collection Types（集合型、Array とか Dictionary）
**Array** と **Dictionary** の二種類の **Collection Type** を扱う
Swift は何れの型を正しく評価し開発時にエラーとして分かる

### Arrays （配列）
同じ値を何度も保持できる
どんなオブジェクトでも保持できる

#### Array Type Shorthand Syntax（基本シンタックス）
**Array<型>** で明示的にしていできる
**型[]** を使った書き方もある　＜ーこっちが preferred らしい

#### Array Literals（配列リテラル）
Shorthand なやりかたは、角括弧[] で括る

> [値1, 値2, 値3]

以下は、"買い物リスト" に **String** の値を指定して配列を生成している

```swift
var 買い物リスト: String[] = ["卵", "牛乳"]
```

"買い物リスト" は "文字列集合配列" として宣言され、配列値に文字列のみを許可する

> **NOTE**
> 可変長として扱いたいので **var** で宣言している

Swift には type inference （推論機能）があるので、以下のようにも書け、以下の場合は、文字列のみ許可される

```swift
var 買い物リスト = ["卵", "牛乳"]
```

#### Accessing and Modifying an Array（配列操作・変更）
メソッドとプロパティを使って操作・変更ができる

##### **count**

配列の要素数を数える

```swift
println("買い物リストにある個数は \(買い物リスト.count) 個.")
```

##### **isEmpty**
**count** property　が 0 のショートカット

```swift
if 買い物リスト.isEmpty {
   println("買い物リストは空です")
}
```

##### append または （+=）
要素を追加

```swift
買い物リスト.append("小麦粉")
買い物リスト += "ベーキングパウダー"
買い物リスト += ["チーズ", "バター"]
```

最初の値

```swift
var firstItem = shoppingList[0]
// firstItem は 卵
```

最初の値を更新する場合

```swift
firstItem[0] = "卵6個"
```

以下みたいな書き方も

```swift
買い物リスト[6...8] = ["バナナ", "リンゴ"]
// "買い物リスト" が　7アイテムに
```

**insert** を使って追加

```swift
買い物リスト.insert("シロップ", atIndex:0)
// "買い物リスト" が 9アイテムになる
// シロップが最初の値になる
```

**removeAtIndex** を使って削除
戻り値は削除したアイテム

```swift
let シロップ = 買い物リスト.removeAtIndex(0)
// 削除したアイテムが戻り値で買い物リストは 8アイテムになる
```

#### Iterating Over an Array（配列の展開、イテレート）
**for-in** loop でイテレートできる

```swift
for item in shoppingList {
    println(item)
}
// 卵6個
// 牛乳
// 小麦粉
// ベーキングパウダー
// チーズ
// バター
// バナナ
// リンゴ
```

#### Creating and Initializing an Array （配列生成）
イニシャライザーを使って空の配列を生成することができる

```swift
var someInts = Int[]()
println("someInts は Int[]　型でアイテムは \(someInts.count) 個.")
// "someInts は Int[]　型でアイテムは 0 個."
```

**Int[]** が指定されているので、Int型の配列になる

```swift
someInt.append(3)
// someInt は数値の値一個保持している
someInts = []
// someInt は数値型で初期かされる
```

初期値の指定もできる

```swift
var threeDoubles = Double[](count: 3, repeatedValue: 0.0)
// threeDoubles は Double[]型で [0.0, 0.0, 0.0] になる

var anotherThreeDoubles = Array(count: 3, repeatedValue: 2.5)
// anotherThreeDoubles は Double[]とみなされ値は [2.5, 2.5, 2.5]

var sixDoubles = threeDoubles + anotherThreeDoubles
// sixDoubles は Dobule[]とみなされ値は [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
```

### Dictionaries（ディクショナリ・連想配列）
ディクショナリに保持する要素の値は必ず型をもつ
明示的に指定したい推論を使ったりして型をセットする
**Dictionary<キー型, 値型>** となる
ObjCはどんなオブジェクトも保持する事ができた
**Key型** は hashable でなければならない
String, Int, Double, Bool はデフォルトで hashable

#### Dictionary Literals （ディクショナリ・連想配列リテラル）
角括弧[] で以下のように括る

> [キー1: 値1, キー2: 値2, キー3: 値3]

例えば

```swift
var airports: Dictionary<String, String> = ["TYO": "Tokyo", "DUB": "Dublin"]
```

上記は、明示的にキー型と値型をStringとしてイニシャライズ
var を使ってるので可変長（mutable）

推論を使って以下のようにも宣言できる

```swift
var airports = ["TYO": "Tokyo", "DUB": "Dublin"]
```

#### Accessing and Modifying a Dictionary（ディクショナリ・連想配列操作、更新）
**count** プロパティはリードオンリーで要素の数を返す

```swift
print("airportsディクショナリの要素は \(airports.count) です。")
// prints "airportsディクショナリの要素は 2　です。
```

新しくキーを追加

```swift
airports["LHR"] = "London"
```

キーの更新

```swift
airports["LHR"] = "London Heathrow"
```

**updateValue(forKey:)** を使うとキーが無い場合追加であるば場合更新
更新の場合は、更新前のオプショナル値を返す
例えば、戻り値が **String** の場合 **String?** を返す

```swift
if let oldValue = airports.updateValue("Dublin International", forKey: "DUB") {
    println("DUB は \(oldValue) だった.")
}
// prints "DUB は Dublin だった."
```

キーの値はオプショナル値なので、以下のようにも書ける

```swift
if let airportName = airports["DUB"] {
    println("空港の名前は \(airportName).")
} else {
    println("空港コードは存在しなし.")
}
// prints "空港の名前は Dublin International."
```

nil を使って削除することもできる

```swift
airport["APL"] = "Apple Intenational"
// Apple Intenational は存在しないので、削除
airport["APL"] = nil
```

**removeValueForKey** を使うと削除した値が取得できる
無い場合 nil を返す

```swift
if let removedValue = airports.removeValueForKey("DUB") {
    println("削除された空港 \(removedValue).")
} else {
    println("DUBの値がディクショナリに存在していない")
}
// prints "削除された空港 Dublin International."
```

#### Iterating Over a Dictionary （ディクショナリ・連想配列展開、イテレート）
**for-in** loop で展開できて、tuple(key, value)を返す

```swift
for (airportCode, airportName) in airports {
    println("\(airportCode): \(airportName)")
}
// TYO: Tokyo
// LHR: London Heathrow
```

**keys** プロパティでキーを返し **values** プロパティで値を返す

```swift
for airportCode in airports.keys {
    println("Airport code: \(airportCode)")
}
// Airport code: TYO
// Airport code: LHR
 
for airportName in airports.values {
    println("Airport name: \(airportName)")
}
// Airport name: Tokyo
// Airport name: London Heathrow
```

キーと値をそれぞれ配列に格納したい場合

```swift
let airportCodes = Array(airports.keys)
// airportCodes is ["TYO", "LHR"]
 
let airportNames = Array(airports.values)
// airportNames is ["Tokyo", "London Heathrow"]
```

> **NOTE**
> Dictionary のキーは順不同でキーの順序は展開するときに順序立つ

#### Creating an Empty Dictionary（ディクショナリ・連想配列生成）

```swift
var namesOfIntegers = Dictionary<Int, String>()
namesOfIntegers[16] = "siteen"
// namesOfInteger は １つのキーと値のペアを保持
nameOfIntegers = [:]
// nameOfInteger は角括弧とコロンを使って初期化されて空の状態になる
```

#### Mutability of Collections （可変について）
* Dictionary
 * 定数の場合、キーも値もサイズも変更できない

* Array
 * 定数の場合、サイズは変更できないが値は変更できる

> **NOTE**
> 基本 immutable を使って、可変の場合のみ mutable にする方が優しい