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 ...
随机推荐
- 基于netty的群聊
基于netty的群聊 学了一段时间的netty知识,现在通过这个基于console的程序来对netty的相关接口做个简单的应用. 准备 依赖 <dependency> <groupI ...
- Nuts.js01
1.简介 Vue ssr框架.支持vue2,vue-router,vuex,vue server render, vue meta 2.基本使用: vue init nuxt-community/ko ...
- vue学习笔记(四)
一.vue-router 1.简介 我们经常使用vue开发单页面应用程序(SPA).在开发SPA过程中,路由是必不可少的部分,vue的官方推荐是vue-router.单页面应用程序看起来好像是一个页面 ...
- 逐行分析jQuery2.0.3源码-完整笔记
概览 (function (){ (21 , 94) 定义了一些变量和函数 jQuery=function(); (96 , 293) 给jQuery对象添加一些方法和属性; (285 , 347) ...
- Windows下利用virtualenvwrapper指定python版本创建虚拟环境
默认已安装virtualenvwrapper 一.添加环境变量(可选) 在系统环境变量中添加 WORKON_HOME ,用来指定新建的虚拟环境的存储位置,如过未添加,默认位置为 %USERPROFIL ...
- Git建立本地分支和远程分支的映射关系
git branch -vv:查看本地分支和远程分支的映射关系 在切换分支前,须本地建立新分支,例如:git branch release/v1.1 //本地建立release/v1.1分支成功后 ...
- Spring Ioc 依赖查找
Spring ioc 有依赖查找和依赖注入,之前不太明白依赖查找是什么意思,翻了一大堆博客看了好多定义也不太清楚 ,后来看了小马哥视频,他通过代码演示,清楚地讲解了什么是 依赖查找以及几种依赖查找的方 ...
- Android网络开发
1. WebView用法 ①布局文件新建一个WebView,特别注意线性布局和控件的宽高都要匹配父控件 <LinearLayout xmlns:android="http://sche ...
- search(3)- elastic4s-QueryDSL
elastic4s是elasticsearch一个第三方开发的scala语言终端工具库(Elastic4s is a concise, idiomatic, reactive, type safe S ...
- ngzorro draw 第一次打开 ERROR TypeError: Cannot read property 'overlayElement' of undefined
at NzDrawerComponent.push../node_modules/ng-zorro-antd/fesm5/ng-zorro-antd.js.NzDrawerComponent.trap ...