当前位置: 首页 > article >正文

【C#】List.ForEach方法

List.ForEach方法

  • List.ForEach方法
    • MSDN 文档
    • 回到修改主题
    • C#中foreach和list.ForEach的区别
    • 111--Id:1,Name:1 222--Id:10,Name:1 111--Id:2,Name:2 222--Id:200,Name:2 111--Id:4,Name:4 222--Id:40,Name:4
    • List 常用属性
    • 参考文章

List.ForEach方法

今天冯同学在研究DataTable更新数据时,传统做法遍历DataTable(很多人可能会说为何还用DT,历史原因不做探讨)。不过也说明了如果是List就可以利用lambda表达式处理。后来冯神就提到ForEach可以精简代码。那我们就来学习下List.ForEach方法吧。
DataTable 转List:
var var_dtTable = dtTable.AsEnumerable().toList();
简单介绍:
Lamdba是延迟执行的,实际上什么都没有发生,当真正使用对象的时候(例如调用:First, Single, ToList….的时候)才执行。

  1. Where语句使用
var var_dtTable = dtTable.AsEnumerable().Where<DataRow>(W => W["NAME"].ToString()=="张三");
int count = var_dtTable.Count<DataRow>();//获取dtTable中NAME为张三的个数
  1. Average语句使用
int avg = dtTable.AsEnumerable().Average<DataRow>(A => float.Parse(A["avg_name"].ToString()))
//获取dtTable中avg_name列的平局数
  1. GroupBy
DataTable dtTable = new DataTable();//数据源
DataTable dtResult = new DataTable();
dtResult.Columns.Add("groupBy_name", typeof(string));
dtResult.Columns.Add("sum_name", typeof(int));
dtResult.Columns.Add("count_name", typeof(int));
var var_dtTable= dtTable.AsEnumerable().GroupBy(G => G["groupBy_name"].ToString()).Select(S => new {
               groupBy_name= s.Key,//获取分组的值
               sum_name= s.Sum(m => m.Field<int>("sum_name")),//获取列名为sum_name数据的和
               count_name= s.Count(m => m.Field<int>("count_name"))//获取列名为count_name数据的个数
               });
var_dtTable.ToList().ForEach(f=> dtResult.Rows.Add(f.groupBy_name,f.sum_name,f.count_name);
//对应的顺序为dtResult列的顺序
  1. OrderBy
DataTable dtTable = new DataTable();//数据源
dtTable = dtTable.AsEnumerable().OrderByDescending(o => o["OrderBy_name"]).CopyToDataTable();//降序
dtTable = dtTable.AsEnumerable().OrderBy(o => o["OrderBy_name"]).CopyToDataTable();//升序
  1. Distinct
DataTable dtTable = new DataTable();//数据源
dtTable = dtTable.AsEnumerable().Distinct(new ColumnEquals("column_name")).CopyToDataTable();
//column_name是要Distinct列的名字

MSDN 文档

定义
命名空间:
System.Collections.Generic
程序集:
System.Collections.dll
对 List 的每个元素执行指定操作。

public void ForEach (Action<T> action);

参数
action
Action
要对 List 的每个元素执行的 Action 委托。

List<string> names = new List<string>();
names.Add("Bruce");
names.Add("Alfred");
names.Add("Tim");
names.Add("Richard");

// Display the contents of the list using the Print method.
names.ForEach(Print);

// The following demonstrates the anonymous method feature of C#
// to display the contents of the list to the console.
names.ForEach(delegate(string name)
{
    Console.WriteLine(name);
});

void Print(string s)
{
    Console.WriteLine(s);
}

/* This code will produce output similar to the following:
* Bruce
* Alfred
* Tim
* Richard
* Bruce
* Alfred
* Tim
* Richard
*/

居然可以调用委托函数,这个简直太方便了。
比如是一个邮件列表:可以在委托方法中推送邮件。当然传统遍历也是可以的。
代码显得优雅,简洁了。

回到修改主题

通常我们对符合条件的List进行部分更新。lambda表达式where关键字处理即可。

//1.Where条件过滤
list.Where(a =>string.IsNullOrWhiteSpace(a.Id) && (!a.Called || (a.Called && _checkCalled.Checked))).ToList();
//2.相当于SQL语句 select * from Study where Stuid in (1,5);
list= list.Where(a => "1,5".Contains(a.Stuid)).ToList();

//List.Foreach
//1.指定某条数据 Check为true,箭头函数=>简化
 list.ForEach((itm) =>
                   {
                     if (txtOsaCbiMemolst.Tag.ToString().Contains(itm.BiId))
                        {
                          itm.Check = true;
                        }
                    });
 //2.全部为true 
   list.ForEach(m=>m.Check = true);


是不是很方便呢?

C#中foreach和list.ForEach的区别

  1. 在foreach和list.ForEach中使用list.Remove()
  2. 在foreach中是不能使用list.Remove(),否则在进入下一个循环就会报异常,所以,如果有使用之后就必须break;

在.ForEach()中,要注意,在.net framework 4.5 会报异常:集合已修改;可能无法执行枚举操作。在.net framework4 3.5 3.0 2.0这几个版本下,可以直接使用list.Remove(),但如果在使用Remove()后下一项是不会遍历到,会自动用下下项。如下代码:

List<Person> list = new List<Person>(){
                new Person(){ Id=1,Name="1"},
                new Person(){ Id=2,Name="2"},
                new Person(){ Id=3,Name="3"},
                new Person(){ Id=4,Name="4"},
            };
            list.ForEach(item =>
            {
                Console.WriteLine(string.Format("111--Id:{0},Name:{1}", item.Id, item.Name));
                if (item.Id == 2)
                {
                    list.Remove(item);
                    item.Id = item.Id * 10;
                }
                item.Id = item.Id * 10;
                Console.WriteLine(string.Format("222--Id:{0},Name:{1}", item.Id, item.Name));
            });
            Console.WriteLine("------------");
            list.ForEach(item => Console.WriteLine(string.Format("Id:{0},Name:{1}", item.Id, item.Name)));

结果:

111–Id:1,Name:1
222–Id:10,Name:1
111–Id:2,Name:2
222–Id:200,Name:2
111–Id:4,Name:4
222–Id:40,Name:4

Id:10,Name:1
Id:3,Name:3
Id:40,Name:4

就是在id=2这项remove后还会对这项进行操作,但在进入下一项是id=4,而id=3这项没有遍历到
所以如果想删除id=2和id=3这两项,结果是id=3是删除不了,如下:

list.ForEach(item =>
            {
                if (item.Id == 2 || item.Id==3)
                {
                    list.Remove(item);
                }
            });
list.ForEach(item => Console.WriteLine(string.Format("Id:{0},Name:{1}", item.Id, item.Name)));

结果:

Id:1,Name:1
Id:3,Name:3
Id:4,Name:4

只删除了id=2这项,所以想删除list中的项,最好还是用for

for (int i = 0; i < list.Count; i++)
{
	if (list[i].Id == 2 || list[i].Id == 3)
    	{
        	list.Remove(list[i]);
            i--;
        }
}

注意删除后,i–;

或者使用list.RemoveAll(),如下:

list.RemoveAll(item => { return item.Id == 2 || item.Id == 3; });
list.ForEach(item => Console.WriteLine(string.Format("Id:{0},Name:{1}", item.Id, item.Name)));

所以,想删除list中的项,最好不用使用foreach和list.ForEach,而是使用for或list.RemoveAll

2. 在list.ForEach()中不能使用continue或者break

如果在遍历到某个特殊项的时候,不用遍历后面的项,需要break,这种情况使用foreach

3.list.ForEach()的使用
见上文MSDN说明

List 常用属性

List的方法和属性 方法或属性 作用

Capacity 用于获取或设置List可容纳元素的数量。当数量超过容量时,这个值会自动增长。您可以设置这个值以减少容量,也可以调用trin()方法来减少容量以适合实际的元素数目。

Count 属性,用于获取数组中当前元素数量

Item( ) 通过指定索引获取或设置元素。对于List类来说,它是一个索引器。

Add( ) 在List中添加一个对象的公有方法

AddRange( ) 公有方法,在List尾部添加实现了ICollection接口的多个元素

BinarySearch( ) 重载的公有方法,用于在排序的List内使用二分查找来定位指定元素.

Clear( ) 在List内移除所有元素

Contains( ) 测试一个元素是否在List内

CopyTo( ) 重载的公有方法,把一个List拷贝到一维数组内

Exists( ) 测试一个元素是否在List内

Find( ) 查找并返回List内的出现的第一个匹配元素

FindAll( ) 查找并返回List内的所有匹配元素

GetEnumerator( ) 重载的公有方法,返回一个用于迭代List的枚举器

Getrange( ) 拷贝指定范围的元素到新的List内

IndexOf( ) 重载的公有方法,查找并返回每一个匹配元素的索引

Insert( ) 在List内插入一个元素

InsertRange( ) 在List内插入一组元素

LastIndexOf( ) 重载的公有方法,,查找并返回最后一个匹配元素的索引

Remove( ) 移除与指定元素匹配的第一个元素

RemoveAt( ) 移除指定索引的元素

RemoveRange( ) 移除指定范围的元素

Reverse( ) 反转List内元素的顺序

Sort( ) 对List内的元素进行排序

ToArray( ) 把List内的元素拷贝到一个新的数组内

trimToSize( ) 将容量设置为List中元素的实际数目

参考文章

[1]: MSDN
[2]: C#中foreach和list.ForEach的区别
[3]: Lamdba及DataTable AsEnumerable()的使用


http://www.kler.cn/a/4888.html

相关文章:

  • 下载导出Tomcat上的excle文档,浏览器上显示下载
  • 做抖音起号的五件套是什么?抖音五件套怎么搭建?
  • VisualDCT用户手册
  • Synchronized锁升级之无锁和偏向锁
  • 【计算机视觉】COCO Caption数据集简单介绍
  • 032:cesium修改默认地图源,动态指定地图
  • Redis7笔记(正在更新中)
  • 【华为OD机试 2023最新 】 优选核酸检测点(C++)
  • 优思学院|平衡计分卡是什么?
  • 网站流量飙升背后:外贸企业谷歌SEO优化实战经验分享
  • Prometheus监控实战系列二十五: Thanos介绍
  • Linux 监控进程创建行为
  • Java设计模式-4、适配器模式
  • 【Hydro】龙格-库塔方法的公式推导
  • ChatGPT背后有哪些关键技术?CSIG企业行带你一探究竟
  • PyTorch 深度学习实战 | 基于生成式对抗网络生成动漫人物
  • JavaScript中bind的用法
  • STM32基于STM32CubeMX DMA + EXTI读取DS1307数据
  • 人大金仓数据库CentOS7安装简述
  • Windows7操作系统
  • 电脑图片压缩到200k以内怎么办?怎么让图片小于200kb?