簡體   English   中英

LINQ GroupBy 除了 null 值

[英]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   |
|--------|--------|

所需 output

| 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM