読者です 読者をやめる 読者になる 読者になる

hachinoBlog

hachinobuのエンジニアライフ

SwiftのArrayとDictionaryの使い方

背景

基本的な言語仕様はふんわりと学んだので、今後多用するであろうArrayとDictionaryの使い方を調べたのでメモ。

Array サンプルコード

// immutableなString型の配列
let names: String[] = ["name5", "name2", "name1", "name3"]

//各データを取得
let name1 = names[0] //name5
let name2 = names[1] //name2
let name3 = names[2] //name1
let name4 = names[3] //name3

//各件数
names.capacity // 4
names.startIndex // 0
names.endIndex // 4
names.count // 4


// mutableなString型の配列
var programLang = ["Objective-C", "Java"]

// データ追加
programLang.append("Swift") // [Objective-C, Java, Swift]
programLang += "Python" // [Objective-C, Java, Swift, Python]

let addLang = ["Ruby", "PHP"] 
programLang.extend(addLang) // [Objective-C, Java, Swift, Python, Ruby, PHP]
programLang += ["Scala", "JavaScript"] // [Objective-C, Java, Swift, Python, Ruby, PHP, Scala, JavaScript]

programLang.insert("ひまわり", atIndex: 0) // [ひまわり, Objective-C, Java, Swift, Python, Ruby, PHP, Scala, JavaScript]

// 配列の中身を逆順にする
programLang.reverse() // [ひまわり, Objective-C, Java, Swift, Python, Ruby, PHP, Scala, JavaScript]

// 配列内をソート(降順)
sort(programLang) { $0 > $1 } // [ひまわり, Swift, Scala, Ruby, Python, PHP, Objective-C, JavaScript, Java]

// 配列内をソート(昇順)
sort(programLang) { $0 < $1 } // [Java, JavaScript, Objective-C, PHP, Python, Ruby, Scala, Swift, ひまわり]

// programLang配列のインデックスが0,1,2のデータを取得
programLang[0...2] // [Java, JavaScript, Objective-C]

// programLang配列のインデックスが0,1のデータをCとC#にする
programLang[0...1] = ["C", "C#"] // [C, C#, Objective-C, PHP, Python, Ruby, Scala, Swift, ひまわり]

// 先頭にCがつく言語を取得
programLang.filter { $0.hasPrefix("C") } // [C, C#]

// 各言語データの先頭に Language: を付与
programLang.map { "Language: \($0)" } // [Language: C, Language: C#, Language: Objective-C, Language: PHP, Language: Python, Language: Ruby, Language: Scala, Language: Swift, Language: ひまわり]

// 指定インデックスに該当するデータ削除
programLang.removeAtIndex(0) // [C#, Objective-C, PHP, Python, Ruby, Scala, Swift, ひまわり]

// インデックス0,1,2のデータを削除
programLang[0...2] = []  // [Python, Ruby, Scala, Swift, ひまわり]

// 配列の最後に格納されているデータを削除
programLang.removeLast()  // [Python, Ruby, Scala, Swift]

// 全て削除
programLang.removeAll()  // []

// copyとunshare
// mutableな配列
var numbersA: Int[] = [1, 2, 3]
var numbersB: Int[] = numbersA
var numbersC: Int[] = numbersA.copy() // numbersAをcopy

numbersA[0] = 0
println(numbersA)  // [0, 2, 3]
println(numbersB)  // [0, 2, 3]
println(numbersC)  // [1, 2, 3]

// copyしたnumbersBをunshare()
numbersB.unshare()
numbersA[1] = 5
numbersC[0...1] = [6, 7]

println(numbersA)  // [0, 5, 3]
println(numbersB)  // [0, 2, 3] unshareしたので参照データでなくなった
println(numbersC)  // [6, 7, 3]

Objective-CのNSArrayと同じように使えるけど += で配列にデータを追加できたりsortが用意されていたりで柔軟で使いやすい印象。


Dictionaries サンプルコード

// 初期化
var personInfo: Dictionary = ["name": "hachinobu", "age": 28]

// データ追加
personInfo["sex"] = "man"

// データ取得
personInfo["name"] //  hachinobu
personInfo["age"]    //  28
personInfo["sex"]    //  man

// 格納件数
personInfo.count //  3

// keyの配列を取得
let keys: Array = Array(personInfo.keys)  //  [sex, name, age]

// valueの配列を取得
let values: Array = Array(personInfo.values) //  [man, hachinobu, 28]

// Dictionaryにnameというkeyでデータが格納されているかチェック、なければ追加する
if let name = personInfo["name"] {
    println("name is \(name)") //  name is hachinobu
} else {
    personInfo["name"] = "hachinobu"
}

// データ更新
personInfo.updateValue("nishinobu", forKey: "name")  //  [sex: man, name: nishinobu, age: 28]


// 既に存在するkeyならupdateで存在しないkeyであればinsertになる
if let age = personInfo.updateValue(29, forKey: "age") {
    println("update")
} else {
    println("insert") 
}

// 追加
personInfo["height"] = 171 //  [age: 29, sex: man, name: nishinobu, height: 171]

// 指定したkeyのデータを削除
personInfo.removeValueForKey("height") //  [age: 29, sex: man, name: nishinobu]

// personInfoのようにvalueの型がOptionalでない場合はvalueにnilを入れると削除扱い
personInfo["name"] = nil //  [age: 29, sex: man]

// 下記のようにvalueの型がOptionalの場合にvalueにnilを入れるとnilが代入される
var optionalDict: Dictionary<String, NSObject?> = ["key1": "A", "key2": "B"]
optionalDict["key1"] = nil // [key2: B, key1: nil]

valueにnil入れて削除とか面白い

valueの型にOptionalを指定すると挙動が変わるので注意が必要