2.6 Swift 3 和Dictionary相關(guān)的基礎(chǔ)知識(shí)

Dictionary是除了Array之外的另一種非常重要的數(shù)據(jù)結(jié)構(gòu)赞庶,它用于把某種形式的key集绰,關(guān)聯(lián)到某種形式的value菠劝。我們來(lái)看一個(gè)例子赛糟。

定義Dictionary

假設(shè)我們要定義一個(gè)數(shù)據(jù)結(jié)構(gòu),用來(lái)保存用戶在泊學(xué)對(duì)某個(gè)視頻的觀看情況摸恍∠ず保可以這樣:

enum RecordType {
    case bool(Bool)
    case number(Int)
    case text(String)
}

let record11: [String: RecordType] = [
    "uid": .number(11),
    "exp": .number(100),
    "favourite": .bool(true),
    "title": .text("Dictionary basics")
]

在上面代碼里,我們用[KeyType: ValueType]的形式來(lái)定義一個(gè)Dictionary立镶。當(dāng)定義好Dictionary之后壁袄,我們就能直接用[Key]來(lái)訪問(wèn)某個(gè)key對(duì)應(yīng)的值了:

record11["uid"]       // number(11)
record11["favourite"] // bool(true)
record11["title"]     // text("Dictionary basics")
record11["invalid"]   // nil

// Optional<RecordType>.Type
type(of: record11["favourite"])

上面例子中的結(jié)果都很直觀。但是有一個(gè)細(xì)節(jié)卻是值得我們注意的媚媒。和Array不同的是嗜逻,[]用在Dictionary的時(shí)候,會(huì)返回一個(gè)Optional類(lèi)型來(lái)確保這種形式的訪問(wèn)安全缭召。因此栈顷,訪問(wèn)不存在的key,并不會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤恼琼。

你怎么理解這種差異呢妨蛹?

這是因?yàn)樗饕@個(gè)概念屏富,對(duì)Array和Dictionary來(lái)說(shuō)晴竞,是截然不同的。對(duì)于Array來(lái)說(shuō)狠半,我們有可能使用的正常索引值只源于Array自身噩死,也就是0..<array.count,因此神年,如果你使用了不在這個(gè)范圍里的值已维,則一定是可以被定性為Bug的,何況已日,我們之前也看到了垛耳,對(duì)于Array,我們幾乎不需要直接使用索引來(lái)訪問(wèn)元素飘千。

而對(duì)于Dictionary來(lái)說(shuō)堂鲜,它包含的內(nèi)容并不直接決定我們可以查詢的內(nèi)容。舉個(gè)例子來(lái)說(shuō)护奈,英漢詞典中也可能并不包含我們要查詢的單詞缔莲。所以,Dictionary中包含的所有鍵值霉旗,從語(yǔ)義上說(shuō)痴奏,并不完全決定了它的使用者會(huì)查詢的值蛀骇,所以,我們也無(wú)法把這類(lèi)問(wèn)題明確的歸因于是Bug读拆。所以擅憔,Swfit為Dictionary的索引查詢操作,提供了optional保護(hù)建椰。要么得到正確的結(jié)果雕欺,要么通過(guò)nil表示要查詢的內(nèi)容不存在。

常用的基本屬性
作為一個(gè)集合類(lèi)型棉姐,Dictionary同樣有count和isEmpty兩個(gè)屬性讀取其元素的個(gè)數(shù)以及判斷其是否為空:

record11.count   // 4
record11.isEmpty // false

另外屠列,我們可以單獨(dú)訪問(wèn)一個(gè)Dictionary的所有keys和所有values:

record11.keys
record11.values

這兩個(gè)屬性也分別是一個(gè)集合,我們可以暫時(shí)忽略掉它們具體的類(lèi)型伞矩,如果要我們要訪問(wèn)它們的每一個(gè)元素笛洛,直接用for循環(huán)或forEach遍歷就好了:

for key in record11.keys { print(key) }
// or
record11.keys.forEach { print($0) }

添加、更新和刪除元素
和Array一樣乃坤,Dictionary也是一個(gè)值類(lèi)型苛让,當(dāng)我們復(fù)制Dictionary對(duì)象的時(shí)候,就會(huì)拷貝Dictionary中的所有內(nèi)容:

var record10 = record11

并且湿诊,直接使用key就可以訪問(wèn)和修改Dictionary的內(nèi)容:

record10['favourite'] = .bool(false) // false
record11['favourite'] // true

如果我們希望更新value的時(shí)候狱杰,同時(shí)獲得修改前的值,還可以使用updateValue(_:forKey:)方法:

record10.updateValue(.bool(true),
    forKey: "favourite") // .bool(false)

從上面的結(jié)果可以看出修改record10并不會(huì)影響record11厅须。

當(dāng)我們要在Dictionary中添加元素時(shí)仿畸,直接給要添加的key賦值就好了:

record10["watchLater"] = .bool(false)
// [
//  "favourite": RecordType.bool(false),
//  "exp": RecordType.number(100),
//  "title": RecordType.text("Directory basics"),
//  "uid": RecordType.number(11),
//  "watchLater": RecordType.bool(false)
// ]
這樣,record10中的內(nèi)容朗和,就變成了5項(xiàng)错沽。而當(dāng)我們要?jiǎng)h除特定的key時(shí),直接把它的值設(shè)置為nil:

record10["watchLater"] = nil
// [
//  "favourite": RecordType.bool(false),
//  "exp": RecordType.number(100),
//  "title": RecordType.text("Directory basics"),
//  "uid": RecordType.number(11)
// ]

這里眶拉,并不是把特定key的值設(shè)置為nil(畢竟Dictionary中value部分的類(lèi)型也不是optional)千埃,而是刪除特定的key。當(dāng)某個(gè)key的value被設(shè)置成nil后忆植,這個(gè)key也就從Dictionary中刪除了放可。

遍歷Dictionary
由于Dictionary同時(shí)包含了key和value,因此朝刊,我們也有多重方式來(lái)遍歷Dictionary耀里。最簡(jiǎn)單的,就是遍歷Dictionary中的每一個(gè)元素:

for (k, v) in record10 {
    print("\(k): \(v)")
}

record10.forEach { print("\($0): \($1)") }

從上面的例子可以看到坞古,遍歷Dictionary和遍歷Array是類(lèi)似的备韧。當(dāng)我們使用for循環(huán)遍歷時(shí),它的每一個(gè)元素都用一個(gè)tuple來(lái)表示痪枫,封裝了每一個(gè)元素的key和value织堂。而當(dāng)使用forEach方法時(shí)叠艳,它會(huì)給它的closure參數(shù)傳遞兩個(gè)值,分別是每一個(gè)元素的key和value易阳。

但是附较,由于Dictionary是一個(gè)無(wú)序集合(unordered collection),因此當(dāng)我們編輯了Dictionary之后潦俺,每次遍歷拒课,訪問(wèn)元素的順序都可能是不同的。如果我們希望按照固定的順序來(lái)訪問(wèn)Dictionary中的元素事示,一個(gè)最簡(jiǎn)單的辦法早像,就是對(duì)key排序后,再進(jìn)行遍歷:

for key in record10.keys.sorted() {
    print("\(key): \(record10[key])")
}

What's next?
在了解了Dictionary的基本用法之后肖爵,下一節(jié)卢鹦,我們通過(guò)extension給Dictionary添加一些標(biāo)準(zhǔn)庫(kù)中沒(méi)有但卻常用的操作,以此進(jìn)一步理解Dictionary的用法劝堪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冀自,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子秒啦,更是在濱河造成了極大的恐慌熬粗,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件余境,死亡現(xiàn)場(chǎng)離奇詭異驻呐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)葛超,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)暴氏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)延塑,“玉大人绣张,你說(shuō)我怎么就攤上這事」卮” “怎么了侥涵?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)宋雏。 經(jīng)常有香客問(wèn)我芜飘,道長(zhǎng),這世上最難降的妖魔是什么磨总? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任嗦明,我火速辦了婚禮,結(jié)果婚禮上蚪燕,老公的妹妹穿的比我還像新娘娶牌。我一直安慰自己奔浅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布诗良。 她就那樣靜靜地躺著汹桦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鉴裹。 梳的紋絲不亂的頭發(fā)上舞骆,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音径荔,去河邊找鬼督禽。 笑死,一個(gè)胖子當(dāng)著我的面吹牛总处,可吹牛的內(nèi)容都是我干的赂蠢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辨泳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼虱岂!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起菠红,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤第岖,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后试溯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蔑滓,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年遇绞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了键袱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡摹闽,死狀恐怖蹄咖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情付鹿,我是刑警寧澤澜汤,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站舵匾,受9級(jí)特大地震影響俊抵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坐梯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一徽诲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦谎替、人聲如沸轩拨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)亡蓉。三九已至,卻和暖如春喷舀,著一層夾襖步出監(jiān)牢的瞬間砍濒,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工硫麻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留爸邢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓拿愧,卻偏偏與公主長(zhǎng)得像杠河,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子浇辜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容