C# 便捷实现可迭代对象间的赋值
都是迭代,为啥我一定要用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真好用!
C# 便捷实现可迭代对象间的赋值的更多相关文章
- C++ 对象间的赋值与拷贝构造函数
1.对象间的赋值 /***A.h文件***/ #pragma once class A { public: int va; A(void); A(char* name); A(const A& ...
- 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】
Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...
- 孤荷凌寒自学python第十六天python的迭代对象
孤荷凌寒自学python第十六天python的迭代对象 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 迭代也就是循环. python中的迭代对象有相关的如下几个术语: A容器 contrai ...
- 【ES6】迭代器与可迭代对象
ES6 新的数组方法.集合.for-of 循环.展开运算符(...)甚至异步编程都依赖于迭代器(Iterator )实现.本文会详解 ES6 的迭代器与生成器,并进一步挖掘可迭代对象的内部原理与使用方 ...
- NSNotification,NSNotificationCenter的使用、iOS中五种对象间传值的方式
学习内容 NSNitification与NotificationCenter(通知与通知中心) 通知的使用 [[NSNotificationCenter defaultCenter]addObserv ...
- Python迭代器,可迭代对象,生成器
迭代器 迭代器(iterator)有时又称游标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如链表或阵列)上遍访的界面,设计人员无需关心容器物件的内存分配的实现细节. ...
- 使用AutoMapper进行对象间映射
在开发过程中,难免遇到下面这种情况:两个(或多个)对象所拥有的大多数属性是重复的,我们需要在对象间进行映射(即将一个对象的属性值赋给另一个对象.通常我们可以进行如下操作: A a=new A(); a ...
- Python中的可迭代对象与迭代器对象
刚刚学习Python,对“可迭代对象”和"迭代器对象"的个人理解,不知道对不对. 1.几个概念 (1)迭代工具:包括for循环.列表解析.in成员关系测试.....等等在内的,用于 ...
- Python生成器、迭代器、可迭代对象
把一个列表[]改成()就创建了一个生成器:generator,generator保存的是算法. 可以用于for循环的数据类型:1.集合类型:list tuple dict set str2.gener ...
随机推荐
- Java多态实现的机制
Java提供了编译时多态和运行时多态两种多态机制.前者是通过方法重载实现的,后者是通过方法的覆盖实现的. 在方法覆盖中,子类可以覆盖父类的方法,因此同类的方法会在父类与子类中有着不同的表现形式. 在J ...
- 【原创】为什么我的 Kafka 总是连接失败呢?
提出问题 近日助友 Docker 部署 Kafka 服务,服务日志启动正常,但客户端却无法连接 往日曾踩过此坑,然方法均源于博客,其语焉不详,不知为何不行,亦不知为何行,印象不甚深刻,耗费大量时间 为 ...
- frida报错frida.InvalidArgumentError: device not found问题解决方案
一.问题描述 python安装好frida框架后,在安卓端启动了frida-server,启动要hook的应用,在cmd中执行python脚本,报错frida.InvalidArgumentE ...
- python使用while循环实现九九乘法表
a = 1while a <= 9: b = 1 while b <= a: print("%d*%d=%d\t" % (b, a, a * b), end=" ...
- Java基础面试系列(一)
Java基础面试总结(一) 1. 面向对象和面向过程的区别 面向过程 面向对象 性能 高于面向对象 类加载的时候需要实例化,比较消耗资源 三易(易维护,易复用,易扩展) 不如面向对象 具有封装,继承, ...
- windows上用putty从linux上下载文件
我之前使用putty都是直接从网上下的putty.exe,其实如果想下载windows的mis二进制文件,系统安装的话会包含,pscp.psftp.puttygen等一系列的文件. 今天下从服务器上, ...
- Python模块一
logging模块 我们来说一下这个logging模块,这个模块的功能是记录我们软件的各种状态,你们现在和我一起找到红蜘蛛的那个图标,然后右键找一找是不是有个错误日志.其实每个软件都是有错误日志的,开 ...
- 转载:Nginx 相关介绍
转载自:https://www.cnblogs.com/wcwnina/p/8728391.html Nginx 相关介绍(Nginx是什么?能干嘛?) Nginx的产生 没有听过Nginx?那么 ...
- C#读取静态类常量属性和值
1.背景最近项目中有一个需求需要从用户输入的值找到该值随对应的名字,由于其它模块已经定义了一份名字到值的一组常量,所以想借用该定义.2.实现实现的思路是采用C#支持的反射.首先,给出静态类中的常量属性 ...
- Nginx 入门及基本命令行操作
Nginx 介绍 Nginx 是一个高性能的 Web 服务器,从 2001 年发展至今,由于 Nginx 对硬件和操作系统内核特性的深度挖掘,使得在保持高并发的同时还能够保持高吞吐量.Nginx 还采 ...