[Swft]辞書

5815 ワード

1.Swift辞書の紹介:
1)キー-値タイプデータを格納するために使用され、C++のmapと似ている.キー値は重複できない.主にデータベースへのアクセスの記録を一時的に保存するために使用され、非常に便利である.
2)ディクショナリタイプ名はDictionaryであり、配列と同様にタイプが固定されたデータ構造であり、key-valueのタイプが初期化時にタイプ推定または直接タイプ指定によって決定され、その後変更できないことを指す.
3)初期化と配列類似を定義する:
キー値ペア間用、区切り、キー値間用:区切り、外用[]で囲みます
//       
var person1: Dictionary<String, String> = ["name": "bill", "school": "lanxiang"]
println(person1) // [school: lanxiang, name: bill]

//      [Type: Type]  
var person2: [String: String] = ["name": "peter", "school": "xindongfang"]
println(person2) // [school: xindongfang, name: peter]

//       [Int: Double]   
var test = [12: 32.1, 34: 393.1, 3: 22.9]
println(test) // [12: 32.1, 3: 22.9, 34: 393.1]
は配列と同様に、タイプ導出定義を使用するときに各キー値がタイプに一致しない場合、内部はNSMetableDictionaryで置き換えられます.
同様にletで定義された定数辞書を使用すると、それ自体も要素値も変更できません.
4)Dictionaryは実質的にSwiftの構造体を用いて実現される.
5)空の辞書を作成する:同様に3つの方法、汎用コンストラクタ、タイプコンストラクタ、直接空にする(タイプが確定することを前提とする)
//      
var dict1 = Dictionary<Int, String>()
//      
var dict2 = [Int: String]()
//     ,           
var dict3: [Int: String] = [:] //         ,  :    !
//                         NSMutableDictionary   
var dict4 = [:]

2.辞書へのアクセスと変更:
1)直接値変更とC++のmapへのアクセスは同じです.
var dic = [1: 2, 3: 5]

dic[10] = 17 //               
dic[1] = 5 //                
println(dic[10]) // Optional(17)
println(dic[1]) // Optional(5)
)しかし、オプションタイプの値が出力されているのが見えます.ここでは、SwiftのDictionaryのセキュリティメカニズムについてお話しします.存在しないキー値ペアに対して、アクセスしたら1つのnilしか戻りません.存在する場合は対応する値を返します.存在しないキー値dic[5]が直接使用されたらどうでしょう.例えばdic[5]+2ですが、dic[5]はキー値に対して存在しません.
実はSwiftはこの問題を回避するために、Dictionaryのキー値のうちの値のタイプを自動的に暗黙的にオプションタイプに引き上げます.すなわち、定義するときは[Type:Type]ですが、下位は[Type:Type?]です.そのため、辞書の値を使用するときはdic[5]!+などのパケット解除記号を付けなければなりません.2、そうでないとエラーが発生します.これは、存在しないキー値アクセス時にnilを返す理由です.
var dic: [Int: Int] = [:]

println(dic[3]) // nil
dic[3] = 10
println(dic[3]) // 10
dic[3] + 7 // Bad!     
println(dic[3]! + 7) // 17
)キー値の削除:nilを直接付与する方式と、使用する方式の2つ.removeValueForKey(forKey:)メソッドは、作成キーに対応する値を削除し、古い値を返します(古い値自体が存在しない場合はnilを返しますので、この関数はオプションのタイプを返します):
var dic: [Int: Int] = [1: 3, 10: 59]
println(dic.count) // 2

dic[1] = nil
println(dic[1]) // nil
println(dic.count) // 1

if let oldValue = dic.removeValueForKey(10)
{
    println(dic[10]) // nil
    println(oldValue) // 59
}
println(dic.count) // 0

!以上、if letの使い方として、クイックチェックに特化した新しいテクニックを引き出しました.C言語のif(!flag)と似ています.if funcReturnOptional(...)の使用を避けることができます.=nilのような面倒な形式は、Swiftでよく使われています!そしてif letも判空の場合にしか使えません.Swiftの中の空nilはtrue/falseとは全く関係ないので使えません!flagのようなブール演算;
!if let体に入るとlet定義の定数は必ず値があることを意味するので、Swiftはその定数を確定タイプに設定するので、if let体でこの定数を使用する場合は使用できません!パッケージを分解して通常のタイプとして使用し、これ以上使用すると一挙に使用します!バッグを分解するとエラーが発生します!
4)キー値の修正:直接付与(存在する場合は修正、存在しない場合は追加)と、2つの方法である.updateValue(newValue,forKey:)のように、指定キーに対応する値を変更しながら古い値を返し、古い値が存在しない場合はnilを返し、同様にオプションタイプを返します.
var dic: [Int: String] = [1: "haha", 2: "hihi"]

println(dic[2]) // hihi
dic[2] = "hoho"
println(dic[2]) // hoho

if let oldValue = dic.updateValue("hehe", forKey: 1)
{
    println("   :\(oldValue)") //  if let oldValue    ,                , !   
    println("   :\(dic[1]!)") // dic[1]        ,   !,       Optional()
}

3.辞书の遍歴:全部で3つの方法があります.keysドメインはキーセットを取得する.valuesドメインは値セットを取得し、メタグループは辞書セット全体を分解します.
//    
for key in person.keys
{
    println("ID: \(key)")
} // 2、3、1,               ,           (   )

//    
for value in person.values
{
    println("Name: \(value)")
}

//             
for (key, value) in person
{
    println("ID: \(key), Name: \(value)")
}
同じタイプでないDictionaryの遍歴については、下位のNSMutableDictionaryをas文を使用してDictionaryの形式に変換してから遍歴します.
var dic = [1: 20.3, "haha": 32, 77.4: "good!"]

for key in (dic as Dictionary).keys
{
    println(key)
}

for value in (dic as Dictionary).values
{
    println(value)
}

for (key, value) in (dic as Dictionary)
{
    println("key: \(key), value = \(value)")
}

4.keysとvaluesを配列に変換:強制タイプ変換を直接使用すればよい
var dic: [Int: Double] = [1: 232.23, 2: 948.22, 3: 2948.2]

let keys = Array(dic.keys)
println(keys)

let values = Array(dic.values)
println(values)

5.コレクションのコピー:
1)主に関数パラメータに用いられ、関数のパラメータが集合であればコピーが発生する.
2)Swiftコレクションは値タイプなので、その中の要素はコピーされますが、コレクションの要素にクラスオブジェクトが含まれている場合は特別扱いが必要です!
3)値タイプの要素に対して直接コピーし、クラスオブジェクトの要素に対してはコピー参照(ポインタ)のみであるため、元とコピーのこのフィールドの参照は同じクラスエンティティを指すため、コピーの中でこの参照によってオブジェクトのフィールドを変更すると、元にも影響します.
4)明示的な代入は直接代入記号=を使えばよい.
6.辞書のvalue値のタイプを変換します.
1)字面で表されるInt値にStringを変換するなど、辞書の値を変換する必要がある場合がある.
2)Swfitの変換ルール:Swiftの基本タイプ間の変換にはメンバー関数toType()を使用すればよいが、OCまたはCocoa Libraryのタイプ間の変換やSwiftの基本タイプに移動するにはas文を使用する必要がある.下位がNSMutableDctionaryのSwiftのDictionaryの場合は、asを使用して本当の意味でSwiftのDictionaryに変換する必要があります.
var dic = [1: "20", 2: "abc"]

var val = dic[1]?.toInt() // value      ,                 ?
println(val!) // 20
var dic = ["key1": "200", 3: 30] //     Swift     ,  NSObject,  Swift       as

var val1 = dic[3] as Int //    dic[3] NSObject   ,   as ,             
println(val1) // 30

//    dic["key1"]  NSObject   
//       as             String,  toInt            Int
var val2 = (dic["key1"] as String).toInt()
println(val2!)

//      as? OC Cocoa     Swift     
var val3 = dic[3] as? Int //     Int?  
println(val3!)

var val4 = (dic["key1"] as? String)?.toInt() //    String?   
println(val4!)