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真好用!

相关文章
相关标签/搜索