[TOC] 都是迭代,為啥我一定要用foreach 問題起源於本人的一個練手的撲克牌程式:洗完牌之後要發給場上的三人。 只發給單個人的時候用 foreach 迴圈一下就好了,但三個人就有點麻煩了。 牌組用list保存你可能會想到這樣寫: 對於字典,可以使用 : 可能各位早會這樣弄了,讓各 ...
目錄
都是迭代,為啥我一定要用foreach
問題起源於本人的一個練手的撲克牌程式:洗完牌之後要發給場上的三人。
只發給單個人的時候用 foreach 迴圈一下就好了,但三個人就有點麻煩了。
牌組用list
for (int i = 0; i < PreCard.Count; i++)
{
a.Add(PreCard[i++]);
b.Add(PreCard[i++]);
c.Add(PreCard[i]);
}
或者這樣寫
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 來進行迭代:
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。看名字就知道它就是為此而生的。
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 ,成功的實現了可迭代對象間的賦值。
關於 foreach
在C#中 foreach 語句,能夠進行比for迴圈語句更直接和簡單的對集合的迭代,編譯器會將 foreach 編譯來調用 GetEnumerator 和 MoveNext方法以及Current屬性。
實際上 foreach 語句編譯之後也會產生類似於上面所寫的代碼。實際上這幅圖可以比較清楚的說明一切。
當然你也可以看看我寫的這篇隨筆,瞭解更多細節https://www.cnblogs.com/AD-milk/p/12459944.html
務必看看這裡
其實前面的做法都是捨近求遠....
我一開始寫的時候,覺得那樣做還挺好的。甚至還自信滿滿的點了發送到首頁[捂臉]
然後....當然是馬上就被撤了。我當然是不服的(聲音減弱),於是就發郵件詢問。
結果當然就是被管理員教育了,其實管理員挺耐心,教會了我很多。(隔著屏幕我也不知道對面想不想順著網線打我)
如果你還想保留原來的集合的話,那麼用上面的方法是可行的,如果不想的話,那麼像下麵那樣使用linq
會更好。
下麵就給大家分享更正一下我學到的知識:
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真好用!