本篇內(nèi)容主要講解“Dictionary遍歷的使用方法有哪些”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Dictionary遍歷的使用方法有哪些”吧!
創(chuàng)新互聯(lián)憑借專業(yè)的設(shè)計(jì)團(tuán)隊(duì)扎實(shí)的技術(shù)支持、優(yōu)質(zhì)高效的服務(wù)意識(shí)和豐厚的資源優(yōu)勢(shì),提供專業(yè)的網(wǎng)站策劃、成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、網(wǎng)站優(yōu)化、軟件開發(fā)、網(wǎng)站改版等服務(wù),在成都10余年的網(wǎng)站建設(shè)設(shè)計(jì)經(jīng)驗(yàn),為成都上千多家中小型企業(yè)策劃設(shè)計(jì)了網(wǎng)站。
使用 foreach 遍歷
為了方便演示,先上一段測(cè)試代碼:
var dict = new Dictionary() { [10] = "A10", [20] = "A20", [30] = "A30", [40] = "A40", [50] = "A50" };
1. 直接 foreach dict
如果要拿百分比說(shuō)話,估計(jì)有 50%+ 的小伙伴用這種方式,為啥,簡(jiǎn)單粗暴唄,其他沒(méi)什么好說(shuō)的,直接上代碼:
foreach (var item in dict) { Console.WriteLine($"key={item.Key},value={item.Value}"); }
這里的 item 是底層在 MoveNext 的過(guò)程中用 KeyValuePair 包裝出來(lái)的,如果你不信的話,看下源碼唄:
public bool MoveNext() { while ((uint)_index < (uint)_dictionary._count) { ref Entry reference = ref _dictionary._entries[_index++]; if (reference.next >= -1) { _current = new KeyValuePair(reference.key, reference.value); return true; } } }
2. foreach 中 使用 KeyPairValue 解構(gòu)
剛才你也看到了 item 是 KeyValuePair 類型,不過(guò)的是 netcore 對(duì) KeyValuePair 進(jìn)行了增強(qiáng),增加了 Deconstruct 函數(shù)用來(lái)解構(gòu) KeyValuePair,代碼如下:
public readonly struct KeyValuePair{ private readonly TKey key; private readonly TValue value; public TKey Key => key; public TValue Value => value; public KeyValuePair(TKey key, TValue value) { this.key = key; this.value = value; } public void Deconstruct(out TKey key, out TValue value) { key = Key; value = Value; } }
有了這個(gè)解構(gòu)函數(shù),你就可以在遍歷的過(guò)程中直接拿到 key,value,而不是包裝的 KeyValuePair,這在 netframework 中可是不行的哈,實(shí)現(xiàn)代碼如下:
foreach ((int key, string value) in dict) { Console.WriteLine($"key={key},value={value}"); }
3. foreach keys
前面的例子都是直接對(duì) dict 進(jìn)行 foreach,其實(shí)你還可以對(duì) dict.keys 進(jìn)行 foreach 遍歷,然后通過(guò)遍歷出的 key 對(duì) dict 進(jìn)行類索引器讀取,代碼如下:
foreach (var key in dict.Keys) { Console.WriteLine($"key={key},value={dict[key]}"); }
說(shuō)到這里,不知道你是否有一個(gè)潛意識(shí),那就是 dict 只能通過(guò) foreach 進(jìn)行遍歷,真相是不是這樣的呢? 要尋找答案,還是回頭看一下 foreach 是如何進(jìn)行遍歷的。
public struct Enumerator : IEnumerator>, IDisposable, IEnumerator, IDictionaryEnumerator { public bool MoveNext() { while ((uint)_index < (uint)_dictionary._count) { ref Entry reference = ref _dictionary._entries[_index++]; if (reference.next >= -1) { _current = new KeyValuePair (reference.key, reference.value); return true; } } _index = _dictionary._count + 1; _current = default(KeyValuePair ); return false; }}
仔細(xì)看這個(gè) while 循環(huán),你就應(yīng)該明白,本質(zhì)上它也是對(duì) entries 數(shù)組進(jìn)行遍歷,那底層都用了 while,我是不是可以用 for 來(lái)替換然后循環(huán) dict 呢?哈哈,反正就是模仿唄。
使用 for 遍歷
為了把 MoveNext 中的代碼模擬出來(lái),重點(diǎn)在于這條語(yǔ)句: ref Entry reference = ref _dictionary._entries[_index++];, 其實(shí)很簡(jiǎn)單,_entries 數(shù)組內(nèi)容的提取可以用 Linq 的 ElementAt 方法,是不是~ ,改造后的代碼如下:
for (int i = 0; i < dict.Count; i++) { (int key, string value) = dict.ElementAt(i); Console.WriteLine($"key={key},value={dict[key]}"); }
接下來(lái)是不是很好奇這個(gè) ElementAt 擴(kuò)展方法是如何實(shí)現(xiàn)的,一起看看源碼吧。
public static TSource ElementAt(this IEnumerable source, int index) { IList list = source as IList ; if (list != null) { return list[index]; } if (index >= 0) { using (IEnumerator enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (index == 0) { return enumerator.Current; } index--; } } } }
到此,相信大家對(duì)“Dictionary遍歷的使用方法有哪些”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!