• DataTable、List、PLINQ使用groupby进行分组和分组统计;List、DataTable查询筛选方法


    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();

     收集整理,非原创

  • 相关阅读:
    famous javascript library.
    54陈上有一些技术文章
    codeforces 612A The Text Splitting(扩展欧几里得)
    UVA 11235 Frequent values
    codeforces 604A Uncowed Forces
    nyoj 138 找球号(二)
    codeforces 592A PawnChess
    cidefirces Educational Codeforces Round 2 A. Extract Numbers
    cidefirces Educational Codeforces Round 2 B Queries about less or equal elements
    codeforces Educational Codeforces Round 2 C Make Palindrome
  • 原文地址:https://www.cnblogs.com/elves/p/3944220.html
Copyright © 2020-2023  润新知