如何过滤列表? [英] How do can a list can be filtered

查看:78
本文介绍了如何过滤列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何过滤列表,

如果我有一个模型< list>喜欢



lstEmpDetails:

 EmpName FineAmt PaidAmt 
A 10 -
A - 10
B 50 -
A - 25
C - 100



我需要输出如下:

 EmpName FineAmt PaidAmt 
B 50 -
A - 25
C - 100



如何我可以使用Linq,使用EmpName,FineAmt和PaidAmt来执行此操作

解决方案

下面的表达式执行以下操作:



首先,它按名称和金额(罚款或付费)对记录进行分组。



然后,每组:



它选择所有FineAmt行但跳过同一组中也存在PaidAmt行的数量,因此如果存在未配对的FineAmt行,则这些行将是列表中的唯一元素。如果有更多PaidAmt行而不是FineAmt行,则会产生一个空列表。



然后对PaidAmt执行相反的操作,并将其与之前的连接相同list(这些列表中只有一个会有任何行。)



每个组的结果列表包含输入中任何未配对的行。



注意:查询假定每行中至少有一个r.FineAmt或r.PaidAmt的值不是null。



  var  filteredRows = lstEmpDetails 
.GroupBy(r => new {r.EmpName,Amount = r.FineAmt ?? r.PaidAmt})
.SelectMany(g = >
g.Where(r => r.FineAmt .HasValue)
.Skip(g.Count(r =>!r.FineAmt.HasValue))
.Concat(g.Where(r =>!r.FineAmt.HasValue)
.Skip(g.Count(r => r.FineAmt.Ha sValue))));





更新:

来取代所有EmpName行的剩余总和:



此语句仅按名称对行进行分组,然后计算每个组的余额。



最后,它只选择那些非零余额的组,然后相应地生成FineAmt,PaidAmt列。



注意:这假设你使用int作为数据类型;如果没有,请相应地更改最后一个Select语句。



  var  filteredRows = lstEmpDetails 
.GroupBy(r => r.EmpName)
。选择(g => new {
EmpName = g.Key,
余额= g.Sum( r = > (r.FineAmt ?? 0 ) - (r.PaidAmt ?? 0 ))
})
.Where(r => r.Balance!= 0
。选择(r =>新{
r.EmpName,
FineAmt = r.Balance > 0 ?( int ?)r。平衡: null
PaidAmt = r.Balance < 0 ? ( int ?) - r.Balance: null
});

  var 结果= lstEmpDetails .SkipWhile(x = >  lstEmpDetails.Any(y = >  x.FineAmt == y。 PaidAmt&& x.PaidAmt == y.FineAmt&& x.EmpName == y.EmpName))。ToList(); 





问候..


How can a list be filtered,
If suppose i got a model <list> like

lstEmpDetails:

EmpName  FineAmt  PaidAmt
  A       10        -
  A       -         10
  B       50        -
  A       -         25
  C       -         100


I need the output like:

EmpName  FineAmt  PaidAmt
  B       50        -
  A       -         25
  C       -         100


How can I do this using Linq by using the EmpName,FineAmt and PaidAmt

解决方案

The expression below does the following:

First, it groups the records by name and amount (fine or paid).

Then, for each group:

It selects all the FineAmt rows but skips as many as there are PaidAmt rows also in the same group, so that if there are unpaired FineAmt rows, these will be the only elements in the list. If there are more PaidAmt rows than FineAmt rows, this results in an empty list.

It then does the same thing in reverse for PaidAmt, and concatenates this with the previous list (only one of these lists will have any rows.)

The resulting list, for each group, consists of any unpaired rows in the input.

NOTE: The query assumes that at least one of r.FineAmt or r.PaidAmt in each row has a value other than null.

var filteredRows = lstEmpDetails
                   .GroupBy(r=>new {r.EmpName, Amount=r.FineAmt ?? r.PaidAmt})
                   .SelectMany(g=>
			          g.Where(r=>r.FineAmt.HasValue)
			           .Skip(g.Count(r=>!r.FineAmt.HasValue))
				   .Concat(g.Where(r=>!r.FineAmt.HasValue)
                                            .Skip(g.Count(r=>r.FineAmt.HasValue))));



Update:
To instead get the remaining sums of all the EmpName rows:

This statement groups the rows by name only, then computes the balance for each group.

Finally, it selects only those groups with non-zero balance, then generates the FineAmt, PaidAmt columns accordingly.

NOTE: This assumes you are using int as the data type; if not, change the last Select statement accordingly.

var filteredRows = lstEmpDetails
                   .GroupBy(r=>r.EmpName)
                   .Select(g=>new{
                       EmpName=g.Key, 
                       Balance=g.Sum(r=>(r.FineAmt ?? 0) - (r.PaidAmt ?? 0))
                   })
                   .Where(r=>r.Balance != 0)
                   .Select(r=>new{
                       r.EmpName,
                       FineAmt = r.Balance > 0 ? (int?)r.Balance : null,
                       PaidAmt = r.Balance < 0 ? (int?)-r.Balance : null
                   });


Try this:

var Result = lstEmpDetails.SkipWhile(x => lstEmpDetails.Any(y => x.FineAmt == y.PaidAmt && x.PaidAmt == y.FineAmt && x.EmpName== y.EmpName)).ToList();



Regards..


这篇关于如何过滤列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆