[英]LINQ GroupBy except null values
我的目標是列出重復項,這就是我正在嘗試的:
var duplicates = result
.GroupBy(x => x.col1)
.SelectMany(y => y.Count() > 1 ? y.Where(z => z.col2== decimal.Zero) : y)
.AsEnumerable()
.ToList();
但它已按col1
中的所有null
值分組。
| col1 | col2 |
|--------|--------|
| 1/1/21 | 0.00 |
| 2/1/21 | 120.00 |
| 2/1/21 | 0.00 |
| 3/1/21 | 110.00 |
| null | 140.00 |
| null | 220.00 |
| 6/1/21 | 0.00 |
| 6/1/21 | 0.00 |
| 7/1/21 | 0.00 |
| null | 0.00 |
|--------|--------|
| col1 | col2 |
|--------|--------|
| 1/1/21 | 0.00 |
| 2/1/21 | 120.00 |
| 3/1/21 | 110.00 |
| null | 140.00 |
| null | 220.00 |
| 6/1/21 | 0.00 |
| 7/1/21 | 0.00 |
| null | 0.00 |
|--------|--------|
對於選擇重復這個查詢應該工作:
var duplicates = result
.GroupBy(x => x.col1)
.Where(y => y.Count() > 1)
.SelectMany()
.ToList();
在您的GroupBy()
中,您需要處理col1
為 null 的情況,並為組鍵分配一個唯一值。 Guid
可以很好地完成這項工作。 嘗試這個:
var duplicates = result
.GroupBy(x => x.col1 == null ? Guid.NewGuid().ToString() : x.col1)
.Select(x => x.First())
.ToList();
假設您的域 model 看起來與此類似:
class DomainModel
{
public string Col1 { get; }
public double Col2 { get; }
public DomainModel(string col1, double col2)
{
Col1 = col1;
Col2 = col2;
}
}
出於測試目的,我將使用以下列表(填充您的示例輸入):
var result = new List<DomainModel>
{
new DomainModel("1/1/21", 0.00),
new DomainModel("2/1/21", 120.00),
new DomainModel("2/1/21", 0.00),
new DomainModel("3/1/21", 110.00),
new DomainModel(null, 140.00),
new DomainModel(null, 220.00),
new DomainModel("6/1/21", 120.00),
new DomainModel("6/1/21", 0.00),
new DomainModel("7/1/21", 0.00),
new DomainModel(null, 0.00)
};
如果我們可以依賴排序,那么我們可以將具有相同Col1
的相鄰記錄分組。 為此,我們需要使用MoreLinq 。
IEnumerable<IGrouping<string, DomainModel>> groupedResult = result.GroupAdjacent(c => c.Col1);
現在,如果我們使用以下命令打印出groupedResult
:
foreach (var group in groupedResult)
{
Console.WriteLine(group.Key ?? "null");
foreach (var model in group)
{
Console.WriteLine($"\t{model.Col2}");
}
}
然后我們將看到以下 output:
1/1/21
0
2/1/21
120
0
3/1/21
110
null
140
220
6/1/21
120
0
7/1/21
0
null
0
如果我正確理解您的要求,那么您想要:
null
的組中的所有條目col2
不為 0 且組中有更多條目的條目這些可以翻譯成以下查詢:
var filteredResult = groupedResult.SelectMany(@group =>
@group.Key == null
? @group //If col1 is null then return as is
: @group.Count() == 1
? @group //If there is a single entry in a group then return as is
: @group.Where(c => Math.Abs(c.Col2) > 0.01)); //If there are multiple entries then return those where col2 is not 0
如果我們執行此查詢,output 將如所願:
foreach (DomainModel model in filteredResult)
{
Console.WriteLine($"{model.Col1 ?? "null"} \t {model.Col2}");
}
1/1/21 0
2/1/21 120
3/1/21 110
null 140
null 220
6/1/21 120
7/1/21 0
null 0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.