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();
收集整理,非原創