DataTable、List使用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 > )
{
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 = ; i < names.Length;i++)
{
names[i] = dataTable.Rows[i][].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(, "武汉", "湖北");
tbl.Rows.Add(, "应城", "湖北");
tbl.Rows.Add(, "武汉", "湖北"); 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[] { "", "李一", , "男" });
sourceDT.Rows.Add(new object[] { "", "王二", , "男" }); var groups = sourceDT.AsEnumerable().GroupBy(t => t["Id"].ToString());
foreach (var group in groups)
{
if (group.Count() > )
{
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 = ;
int totalCount = Convert.ToInt32(dtDataAll.Rows.Count);
int totalPage = Convert.ToInt32(Math.Ceiling((double)totalCount / PageSize));
var dtDataAllTemp = dtDataAll.AsEnumerable();
for (var i = ; 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 - )).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, );
Func<DataEntity, DateTime> groupBy3 = x => new DateTime(x.DataTime.Year, , );
//如果指定了时间间隔,就用开始时间,按照特定间隔来分组
if (span > )
{
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, );
groupBy3 = x => new DateTime(dtStart.Year + ((x.DataTime.Year - dtStart.Year) / span) * span, , );
}
var groupByChoice = groupByType == ? groupBy1 : (groupByType == ? 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> { , , , , , , };
var listB = new List<int>(); using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, listA);
ms.Position = ;
listB = (List<int>)bf.Deserialize(ms);
}
}
///使用序列化与反序列化
public void ListDemo_D()
{
var listA = new List<int> { , , , , , , };
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(, , (i) =>
{
Console.WriteLine("ThreadProc: {0}", i);
});
//Parallel设置最大线程数、跳出循环以及终止循环
Parallel.ForEach(list,new ParallelOptions(){ MaxDegreeOfParallelism=}, (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 - )
          where n.Age > && n.Age <
orderby n.CreateTime descending
select n).ToList();

收集整理,非原创

上一篇:Nancy 搭建


下一篇:一个基于nuxt的基础架子,支持aixos,sass,es6,elementUI