C# 便捷實現可迭代對象間的賦值

都是迭代,爲啥我必定要用foreach

​ 問題起源於本人的一個練手的撲克牌程序:洗完牌以後要發給場上的三人。
​ 只發給單我的的時候用 foreach 循環一下就行了,但三我的就有點麻煩了。
​ 牌組用list 保存你可能會想到這樣寫: html

for (int i = 0; i < PreCard.Count; i++)
            {
                a.Add(PreCard[i++]);
                b.Add(PreCard[i++]);
                c.Add(PreCard[i]);
            }

​ 或者這樣寫c#

int i = 0;
            do
            {
                a.Insert(i, PreCard[0]);
                b.Insert(i, PreCard[1]);
                c.Insert(i, PreCard[2]);
                PreCard.RemoveRange(0, 3);
                i++;
            } while (i < PreCard.Count);

​ 但若是還想使用相似迭代器的方法,那麼可使用 GetEnumerator(),由於咱們知道 foreach 裏面實際上就是調用了這個方法。
​ 因此咱們還能夠直接調用 GetEnumerator 和 MoveNext 來進行迭代:3d

IEnumerator ie = PreCard.GetEnumerator();
            while(ie.MoveNext())
            {
                a.Add(ie.Current.ToString());
                ie.MoveNext();
                b.Add(ie.Current.ToString());
                ie.MoveNext(); 
                c.Add(ie.Current.ToString());
            }

若是換成是字典呢?

​ 若是是直接把上面的代碼搬過來,會發現add方法那裏會報錯,須要提供兩個參數,鍵和值。
​ 難道必需要對獲得的 IEnumerator 再用一次 GetEnumerator?
​ 實際上大可沒必要,由於針對這種鍵值對,咱們有一個玩意叫作 IDictionaryEnumerator。看名字就知道它就是爲此而生的。code

IDictionaryEnumerator ie = dict.GetEnumerator();
            while(ie.MoveNext())
            {
                a.Add(ie.Key.ToString(),Convert.ToInt32(ie.Value));
                ie.MoveNext();
                b.Add(ie.Key.ToString(),Convert.ToInt32(ie.Value));
                ie.MoveNext();
                c.Add(ie.Key.ToString(),Convert.ToInt32(ie.Value));
            }

​ 至此咱們經過寫手動擋的 foreach ,成功的實現了可迭代對象間的賦值。htm

關於 foreach

​ 在C#中 foreach 語句,可以進行比for循環語句更直接和簡單的對集合的迭代,編譯器會將 foreach 編譯來調用 GetEnumerator 和 MoveNext方法以及Current屬性。對象

​ 實際上 foreach 語句編譯以後也會產生相似於上面所寫的代碼。實際上這幅圖能夠比較清楚的說明一切。blog


​ 固然你也能夠看看我寫的這篇隨筆,瞭解更多細節https://www.cnblogs.com/AD-milk/p/12459944.html編譯器

務必看看這裏

​ 其實前面的作法都是捨近求遠....
string

​ 我一開始寫的時候,以爲那樣作還挺好的。甚至還自信滿滿的點了發送到首頁[捂臉]
​ 而後....固然是立刻就被撤了。我固然是不服的(聲音減弱),因而就發郵件詢問。
​ 結果固然就是被管理員教育了,其實管理員挺耐心,教會了我不少。(隔着屏幕我也不知道對面想不想順着網線打我)
​ 若是你還想保留原來的集合的話,那麼用上面的方法是可行的,若是不想的話,那麼像下面那樣使用linq 會更好。it

​ 下面就給你們分享更正一下我學到的知識:

var PreCard = new Queue<string>() ;
            PreCard.Enqueue("03a");
            PreCard.Enqueue("03b");
            PreCard.Enqueue("03c");
            PreCard.Enqueue("03d");
            PreCard.Enqueue("04a");
            PreCard.Enqueue("04b");
           
            var players = new List<List<string>>
            {
                new List<string>(),
                new List<string>(),
                new List<string>()
            };

            while (PreCard.Count > 0)
            {
                players.ForEach(p => p.Add(PreCard.Dequeue()));
            }

            players.ForEach(p =>
            {
                p.ForEach(c => Console.Write(c + " "));
                Console.WriteLine();
            });

對於字典,可使用KeyValuePair

var PreCard = new Queue<KeyValuePair<string, int>>(
                new Dictionary<string, int>
                {
                    {"a",1 },{"b",2 },{"c",3 },{"d",4 },{"e",5 },{"f",6 }
                });
            var players = new List<List<KeyValuePair<string, int>>>
            {
                 new List<KeyValuePair<string, int>>(),
                 new List<KeyValuePair<string, int>>(),
                 new List<KeyValuePair<string, int>>()
            };

            while (PreCard.Count > 0)
            {
                players.ForEach(p => p.Add(PreCard.Dequeue()));
            }

            players.ForEach(p =>
            {
                p.ForEach(c => Console.Write(c + " "));
                Console.WriteLine();
            });

可能各位早會這樣弄了,讓各位進來實在是很差意思了。

最後說一句,linq真好用!

相關文章
相關標籤/搜索