はじめに
以前はobjcでiOS開発する機会が多かったのですが、最近SwiftでiOS開発をする機会が多いので、Swiftらしいコーディングをしていくために学んだことをまとめていきたいと思います。何か気になることや、もっとよく書けるみたいな意見があれば気軽にコメントお願いします。今回はCollectionTypeに準拠する配列や辞書についてまとめました。
Collection Types
CollectionType Protocol Referenceを見てみるとArray, Set, DictionaryはCollection Types
に準拠していることがわかりますね。Collection Types
に準拠したクラスは複数の明示された型のキーや値を格納することができ、それ以外の方を格納することは出来ません。つまり、キーや値の型を取得する際は想定された型を受け取ることが保証できます。
要素の重複と順序
型によって要素の順序や重複した要素を格納できるかが異なります。
型 | 要素の順序 | 要素の重複 |
---|---|---|
Array | 要素を入れた順 | ◯ |
Set | 順不同 | × |
Dictionary | 順不同 | key × value ◯ |
変数定義
- raywenderlich/swift-style-guideで推奨されている変数定義
// Array
var array: [Int] = []
//Dictionary
var dictionary: [Int: String] = [:]
- Collection Typesで推奨されている変数定義
// Array
var array = [Int]()
var arrayWithValues = ["value1", "value2"]
// Set
var set = Set<Character>()
var setWithValues: Set = ["value1", "value2", "value3"]
//Dictionary
var dictionary = [Int: String]()
var dictionaryWithKeyValue = ["key1": "value1", "key2": "value2"]
//どうしても変数である必要がある場合以外はletで宣言する
let constArray = ["value1", "value2"]
- 以下の定義の仕方は非推奨
var array: [Int] = [Int]()
var array = Array<Int>()
var dictionary: [Int: String] = [Int: String]()
var dictionary = Dictionary<Int, String>()
基本的な使い方
以下の書き方はCollection Typesを参考にしています。
Array
var someInts = [Int]()
//[]
someInts.append(3)
//[3]
someInts += [2, 5]
//[3, 2, 5]
someInts = []
//[]
var threeDouble = [Double](count: 3, repeatedValue: 0.0)
// [0, 0, 0]
var anotherThreeDoubles = [Double](count: 3, repeatedValue: 2.3)
//[2.3, 2.3, 2.3]
var sixDouble = threeDouble + anotherThreeDoubles
//[0, 0, 0, 2.3, 2.3, 2.3]
//要素と一緒に初期化
var shoppingList = ["Eggs", "Milk"]
// ["Eggs", "Milk"]
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
//["Eggs", "Milk", "Chocolate Spread", "Cheese", "Butter"]
shoppingList.count
//5
shoppingList[0] = "two Eggs"
//["two Eggs", "Milk", "Chocolate Spread", "Cheese", "Butter"]
shoppingList[1...2] = ["Bananas", "Apples"]
//["two Eggs", "Bananas", "Apples", "Cheese", "Butter"]
shoppingList.insert("Maple Syrup", atIndex: 0)
//["Maple Syrup", "two Eggs", "Bananas", "Apples", "Cheese", "Butter"]
let mapleSyrup = shoppingList.removeAtIndex(0)
print(mapleSyrup)
//"Maple Syrup"
print(shoppingList)
//["two Eggs", "Bananas", "Apples", "Cheese", "Butter"]
let apples = shoppingList.removeLast()
print(apples)
//"Butter"
print(mapleSyrup)
//["two Eggs", "Bananas", "Apples", "Cheese"]
if shoppingList.isEmpty {
print("empty")
} else {
print("contain value")
}
//contain value
Set
//空のSet
var letters = Set<Character>()
//[]
letters.insert("a")
//{"a"}
letters = []
//[]
//要素と一緒に初期化
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
//{"Rock", "Classical", "Hip hop"}
favoriteGenres.count
//3
favoriteGenres.insert("Jazz")
//{"Rock", "Classical", "Jazz", "Hip hop"}
//Jazzは最後に追加されてないことに注意
if let removedGenre = favoriteGenres.remove("Rock") {
print("removed Rock")
}
//"removed Rock"
if favoriteGenres.contains("Hip hop") {
print("contain Hip hop")
}
//"contain Hip hop"
if favoriteGenres.isEmpty {
print("empty")
} else {
print("contain value")
}
// "contain value"
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
oddDigits.union(evenDigits).sort()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersect(evenDigits).sort()
// []
oddDigits.subtract(singleDigitPrimeNumbers).sort()
// [1, 9]
oddDigits.exclusiveOr(singleDigitPrimeNumbers).sort()
// [1, 2, 9]
-
a.union(b)
: 重複を除くaとbに含まれるすべての要素 -
a.intersect(b)
: aとbので重複している要素 -
a.subtract(b)
: aからaとbで重複している要素を除いた要素 -
a.exclusiveOr(b)
: aとbで重複してない要素
Dictionary
var namesOfIntegers = [Int: String]()
//[:]
namesOfIntegers[16] = "sixteen"
//[16: "sixteen"]
namesOfIntegers = [:]
//[:]
//要素と一緒に初期化
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
//["DUB": "Dublin", "YYZ": "Toronto Pearson"]
airports.count
//2
airports["LHR"] = "London"
//["DUB": "Dublin", "LHR": "London", "YYZ": "Toronto Pearson"]
airports["LHR"] = "London Heathrow"
//["DUB": "Dublin", "LHR": "London Heathrow", "YYZ": "Toronto Pearson"]
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
print(oldValue)
//Dublin
}
print(airports)
//"["DUB": "Dublin Airport", "LHR": "London Heathrow", "YYZ": "Toronto Pearson"]
if let airportName = airports["DUB"] {
print(airportName)
//Dublin Airport
}
airports["APL"] = "Apple International"
//["APL": "Apple International", "YYZ": "Toronto Pearson", "DUB": "Dublin Airport", "LHR": "London Heathrow"]
airports["APL"] = nil
//["YYZ": "Toronto Pearson", "DUB": "Dublin Airport", "LHR": "London Heathrow"]
//APLのキーごと要素がなくなる
if let removedValue = airports.removeValueForKey("DUB") {
print(removedValue)
//Dublin Airport
print(airports)
//["YYZ": "Toronto Pearson", "LHR": "London Heathrow"]
}
if airports.isEmpty {
print("empty")
} else {
print("contain elements")
}
//contain elements
let airportCodes = [String](airports.keys)
//["YYZ", "LHR"]
let airportNames = [String](airports.values)
//["Toronto Pearson", "London Heathrow"]
For-In Loops
要素が複数格納されているCollection Types
に準拠する型はloop処理によって要素を参照することができます。
//Array
let array = ["Qiita", "Swift", "Objective-C", "iOS"]
for value in array {
print(value)
}
//Qiita
//Swift
//Objective-C
//iOS
//enumerate()は配列のindexと値のタプルを返す
for (index, value) in array.enumerate() {
print("index: \(index) value: \(value)")
}
//index: 0 value: Qiita
//index: 1 value: Swift
//index: 2 value: Objective-C
//index: 3 value: iOS
//Dictionary
let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
print("\(animalName)s have \(legCount) legs")
}
// ants have 6 legs
// cats have 4 legs
// spiders have 8 legs
高階関数
Collection Types
に準拠するArray, SetやDictionaryなどはmap
などの高階関数が利用できます。高階関数やClosure
についてはSwiftらしいコーディングを学ぶ 「コレクションに用いる高階関数とClosure」の記事にまとめてあります。