DataTable分组统计:
//使用linq to DataTable group by实现 var query = from t in dt.AsEnumerable() group t by new { t1 = t.Field<string>("name"), t2 = t.Field<string>("sex") } into m select new { name = m.Key.t1, sex = m.Key.t2, score = m.Sum(n => n.Field<decimal>("score")) }; if (query.ToList().Count > 0) { query.ToList().ForEach(q => { Console.WriteLine(q.name + "," + q.sex + "," + q.score); }); }
//分组统计按次数排序 Dictionary<string, string> dicProjectExpectFiveParam = listProject.GroupBy(x => new { x.LHCodeID, x.ParamName }) .Where(p => !sFiveParam.Contains(p.Key.LHCodeID)) .Select(group => new { group.Key, LHCodeIDCount = group.Count() }) .OrderByDescending(t => t.LHCodeIDCount) .ToDictionary(o => o.Key.LHCodeID, p => p.Key.ParamName);
DataTable去除重复的方法:
一、ToTable方法来自动过滤所有重复行的数据,代码如下:
DataTable dt = "您的来源dt"; DataTable dt_new = dt.DefaultView.ToTable(true, "关键列1", "关键列2");
dt_new中存储的就是我们想要的所有不重复行的数据了。
public string[] GetNamesFromDataTable(DataTable dataTable) { DataView dv = dataTable.DefaultView; dataTable = dv.ToTable(true, "Name"); string[] names = new string[dataTable.Rows.Count]; for (int i = 0; i < names.Length;i++) { names[i] = dataTable.Rows[i][0].ToString(); } return names; }
讲解:
1.DefaultView的返回类型是DataView,而DataView的定义就是:
表示用于排序、筛选、搜索、编辑和导航的System.Data.DataTable的可绑定数据的自定义视图。
所以我们在要用到对DataTable进行排序、筛选、搜索、编辑和导航操作时,就要想到用DataView.
2.public DataTable ToTable(bool distinct, params string[] columnNames)方法:
从参数名我们就可以猜出它的意思了。
distinct:表示返回的Data.DataTable是否包含所有列都具有不同值的行,默认为false。
columnNames:表示要包括在返回的System.Data.DataTable中的列名的列表。如果distinct为true,则它会根据columnNames指定的列名进行筛选过滤。
二、
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { DataTable tbl = new DataTable(); tbl.Columns.Add("Id", typeof(System.Int32)); tbl.Columns.Add("City", typeof(System.String)); tbl.Columns.Add("Province", typeof(System.String)); tbl.Rows.Add(1, "武汉", "湖北"); tbl.Rows.Add(2, "应城", "湖北"); tbl.Rows.Add(3, "武汉", "湖北"); IEnumerable <DataRow> r = tbl.AsEnumerable().Distinct(new CityComparer()); //到这一步,r里就是去重复的记录了 foreach (var item in r) { Console.WriteLine(item["Id"] + "," + item["City"] + "," + item["Province"]); } Console.ReadLine(); } } class CityComparer : IEqualityComparer <DataRow> { public bool Equals(DataRow r1, DataRow r2) { return r1["City"] == r2["City"]; } public int GetHashCode(DataRow obj) { return obj.ToString().GetHashCode(); } } }
三、
DataTable sourceDT = new DataTable("Table1"); sourceDT.Columns.Add("Id", System.Type.GetType("System.String")); sourceDT.Columns.Add("Name", System.Type.GetType("System.String")); sourceDT.Columns.Add("Age", System.Type.GetType("System.Int32")); sourceDT.Columns.Add("Sex", System.Type.GetType("System.String")); sourceDT.Rows.Add(new object[] { "10001", "李一", 24, "男" }); sourceDT.Rows.Add(new object[] { "10001", "王二", 23, "男" }); var groups = sourceDT.AsEnumerable().GroupBy(t => t["Id"].ToString()); foreach (var group in groups) { if (group.Count() > 1) { foreach (var row in group) { sourceDT.Rows.Remove(row); } } }
DataTable中AsEnumerable与Cast类似,都可转为Linq统计、排序等;
//运用LinQ,将DataTable转换为集合,再调用集合自带的排序方法进行排序 foreach (DataRow s in dt.Rows.Cast<DataRow>().OrderBy(r => int.Parse(r["Age"].ToString()))) { Response.Write(s["Age"].ToString() + "--" + s["Name"].ToString() + "<br/>"); }
//运用Linq将DataTable转换为集合进行分页(拆分Table) int PageSize = 65536; int totalCount = Convert.ToInt32(dtDataAll.Rows.Count); int totalPage = Convert.ToInt32(Math.Ceiling((double)totalCount / PageSize)); var dtDataAllTemp = dtDataAll.AsEnumerable(); for (var i = 0; i<totalPage; i++) { DataTable dtNew = dtDataAllTemp.Skip(i * PageSize).Take(PageSize).CopyToDataTable(); }
List委托
List<Act_TypeListInfo> listFind = listAllTZ.FindAll(delegate( Act_TypeListInfo f){ return f.MainID == iMainId && f.KeyName == info.ColKeyName && f.CompID == iCompID); });
//linq多表关联分组排序统计 var temp = from ta in areaList join tb in StationList on ta.AreaID equals tb.AreaID join tc in dcMNComple on tb.MN equals tc.Key into temp1 //orderby ta.AreaID group temp1 by new { AreaName = ta.AreaName, AreaID = ta.AreaID } into temp2 select new { AreaName = temp2.Key.AreaName, AreaID = temp2.Key.AreaID, MNCount = temp2.Count(), Comple = temp2.Sum(s => s.Sum(t => t.Value)) };
分组后遍历
List<Cart_Model> list_CartModel = new List<Cart_Model>(); IEnumerable<IGrouping<string, Cart_Model>> query = list_CartModel.GroupBy(pet => pet.ShopId, pet => pet); foreach (IGrouping<string, Cart_Model> info in query) { List<Cart_Model> sl = info.ToList<Cart_Model>();//分组后的集合 //也可循环得到分组后,集合中的对象,你可以用info.Key去控制 foreach (KqiPageSetupInfo set in sl) { } }
//从List中查找另一个List的匹配项 var mnList = listFind.Where(d => listYQ.Select(d1 => d1.YQID).Contains(d.YQID)).ToList(); //或 (FindAll) var mnList = listFind.Where(delegate (T_MNYQInfo f) { foreach (var itemYq in listYQ) { if (f.YQID == itemYq.YQID) { return true; } } return false; }).ToList();
//List中查找不为空的数据,去除重复 var qu = list.Where(x => x.DataTime.HasValue).Select(y => y.DataTime.Value).OrderByDescending(z => z).Distinct(); var listDT = qu.ToList();
//List中按两个值排序 OrderBy先排序 List = List.OrderBy(p => p.id).ThenBy(p => p.sid).ToList();
//List分页 DataPager1.CurrentPageIndex当前页码 PageSize分页大小 var curMNList = mnList.Skip(PageSize * (DataPager1.CurrentPageIndex - 1)).Take(PageSize).ToList();
List分组
//时间分组模式 Func<DataEntity, DateTime> groupBy1 = x => x.DataTime.Date; Func<DataEntity, DateTime> groupBy2 = x => new DateTime(x.DataTime.Year, x.DataTime.Month, 1); Func<DataEntity, DateTime> groupBy3 = x => new DateTime(x.DataTime.Year, 1, 1); //如果指定了时间间隔,就用开始时间,按照特定间隔来分组 if (span > 1) { dtStart = dtStart.Date; groupBy1 = x => dtStart.AddDays(((x.DataTime.Date - dtStart).Days / span) * span); groupBy2 = x => new DateTime(dtStart.Year, dtStart.Month + ((x.DataTime.Month - dtStart.Month) / span) * span, 1); groupBy3 = x => new DateTime(dtStart.Year + ((x.DataTime.Year - dtStart.Year) / span) * span, 1, 1); } var groupByChoice = groupByType == 1 ? groupBy1 : (groupByType == 2 ? groupBy2 : groupBy3); var luTime = grMN.ToLookup(groupByChoice);
/*List对比所有项,判断 listMN1是否所有项存在于 listMN2*/ List<string> listMN1 = new List<string>(){ "399435XYX00003", "399435XYX00001", }; List<string> listMN2 = new List<string>(){ "399435XYXKL117", "399435XYX00003", }; if (listMN1.All(listMN2.Contains)) //true
///深度拷贝 public void ListDemo_B() { var listA = new List<int> { 2, 5, 6, 8, 23, 56, 4 }; var listB = new List<int>(); using (MemoryStream ms = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, listA); ms.Position = 0; listB = (List<int>)bf.Deserialize(ms); } }
///使用序列化与反序列化 public void ListDemo_D() { var listA = new List<int> { 2, 5, 6, 8, 23, 56, 4 }; var listB = JsonConvert.DeserializeObject<List<int>>(JsonConvert.SerializeObject(listA)); }
//并行化处理两个集合 //PLINQ 的 Zip 方法提供了同时遍历两个集合并进行结合元算的方法,并且它可以与其他查询处理操作结合,实现非常复杂的机能。 public static IEnumerable<T> Zipping<T>(IEnumerable<T> a, IEnumerable<T> b) { return a .AsParallel() .AsOrdered() .Select(element => ExpensiveComputation(element)) .Zip( b .AsParallel() .AsOrdered() .Select(element => DifferentExpensiveComputation(element)), (a_element, b_element) => Combine(a_element,b_element)); } //示例中的两个数据源能够并行处理,当双方都有一个可用元素时提供给 Zip 进行后续处理(Combine)。 //Parallel.ForEach 也能实现类似的 Zip 处理: public static IEnumerable<T> Zipping<T>(IEnumerable<T> a, IEnumerable<T> b) { var numElements = Math.Min(a.Count(), b.Count()); var result = new T[numElements]; Parallel.ForEach(a, (element, loopstate, index) => { var a_element = ExpensiveComputation(element); var b_element = DifferentExpensiveComputation(b.ElementAt(index)); result[index] = Combine(a_element, b_element); }); return result; }
ParallelLoopState.Stop() 提供了退出循环的方法,这种方式要比其他两种方法更快。这个方法通知循环不要再启动执行新的迭代,并尽可能快的推出循环。
ParallelLoopState.IsStopped 属性可用来判定其他迭代是否调用了 Stop 方法。
ParallelLoopState.Break() 通知循环继续执行本元素前的迭代,但不执行本元素之后的迭代。最前调用 Break 的起作用,并被记录到 ParallelLoopState.LowestBreakIteration 属性中。这种处理方式通常被应用在一个有序的查找处理中,比如你有一个排序过的数组,你想在其中查找匹配元素的最小 index,
Environment.ProcessorCount 获取最大线程数
//预执行1500w(<)条记录 Parallel.For(0, 15000000, (i) => { Console.WriteLine("ThreadProc: {0}", i); });
//Parallel设置最大线程数、跳出循环以及终止循环 Parallel.ForEach(list,new ParallelOptions(){ MaxDegreeOfParallelism=2}, (p, state1) => { Invoke(p); state1.Break();//Break用于根据条件过滤循环,Break不是Continue,不要搞混了!Break是执行完现有的迭代后跳出! state1.Stop();//Stop方法用于退出Paraller循环,表示立刻退循环,cease=终止 return; //注意:不论是Break还是Stop方法,后面的return语句是必须的,否则当前循环体第13行的语句还是会被执行。 });
AsParallel并行执行
WithDegreeOfParallelism指定并行度--为了不让并行计算占用全部的硬件线程,或许可能要留一个线程做其他事情。
var query2 = (from n in dic.Values.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 1) where n.Age > 20 && n.Age < 25 orderby n.CreateTime descending select n).ToList();
收集整理,非原创