簡體   English   中英

C# Linq 使用多個字段比較列表值並返回不滿足條件的項目

[英]C# Linq Comparing List Values using multiple fields and return item which doesn't satisfy the condition

我有一個這樣的列表稱為結果

{ Id = "8131367", GId = 27720, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 500.00 }
{ Id = "8131368", GId = 27720, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 1500.00 }
{ Id = "8131369", GId = 27720, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 500.00 }
{ Id = "8131370", GId = 27720, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 500.00 }
{ Id = "8131371", GId = 27720, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 500.00 }
{ Id = "8131372", GId = 27720, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 500.00 }
{ Id = "8131373", GId = 27721, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 500.00 }
{ Id = "8131374", GId = 27721, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 500.00 }
{ Id = "8131375", GId = 27721, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 500.00 }
{ Id = "8131376", GId = 27721, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 500.00 }
{ Id = "8131377", GId = 27721, Share = 1.0000, Type = "1029", OPC = "997", IPC = "997", Price = 1500.00 }

我需要根據具有相同值的 GId、Share、Type、OPC、IPC 和具有不同值的價格來過濾列表。 所以從列表中第二個和最后一個價格不同所以我需要從列表項中獲取價格不同且值相同的 rest 的列表或 Id 屬性。

通過使用兩個 Foreach 循環,我能夠得到我需要的東西,但不幸的是,我被要求將其轉換為 LINQ 查詢。 這是我試過的

var items = result.Select(r => result.Where(rr => (r.GId == rr.GId) 
                                                   && (r.Share == rr.Share) 
                                                   && (r.Type == rr.Type) 
                                                   && (r.IPC == rr.IPC) 
                                                   && (r.OPC == rr.OPC) 
                                                   && (r.Price != rr.Price))).ToList();

但是從上面的查詢中我沒有得到我想要的東西,我相信我已經接近我需要的東西,但我缺乏 LINQ 的專業知識。

您可以使用Group by對除Id之外的所有屬性進行分組,如以下代碼:

var items = result.GroupBy(x => new { x.GId, x.Share, x.Type, x.OPC, x.IPC, x.Price })
    .Where(x => x.Count() == 1)
    .SelectMany(x => x.Take(1))
    .ToList();

演示

foreach(Test item in items)
{
    Console.WriteLine($"Id:{item.Id}, GID:{item.GId}, Price:{item.Price}");
}

結果

Id:8131368, GID:27720, Price:1500
Id:8131377, GID:27721, Price:1500

我希望你覺得這有幫助。

這將起作用,但根本沒有優化:

var result2 = result
    .GroupBy(i => new {i.GId, i.Share, i.Type, i.OPC, i.IPC})
    .Select(i1 => i1.LastOrDefault(i2 => i1.Count(i3 => i3.Price == i2.Price) == 1))
    .ToList();

它將返回 ID 為“8131368”和“8131377”的行

編輯此代碼有效,但要求可以避免嵌套循環。 用我的評論檢查 Sajid 的回答:-)

因此,我需要從價格不同且 rest 的值相同的列表項中獲取該列表或 Id 屬性

您可以按包含應該相等的屬性的值元組進行分組,然后將 select 分組與一個以上的元素:

var itemIds = result
    .GroupBy(r => (r.GId, r.Share, r.Type, r.IPC, r.OPC))
    .Where(g => g.Select(r => r.Price).Distinct().Count() > 1) // or Count() == 2, then next clause can be simplified
    .Select(g => 
    {
        var byPrice = g.GroupBy(r => r.Price).ToList();
        
        if(byPrice.Count > 2)
        {
            throw new Exception("Could not determine base price - more than 2 groups");
        }
        
        if (byPrice.All(gg => gg.Count() == 1))
        {
            throw new Exception("Could not determine base price - multiple groups with single element");
        }
        
        return byPrice.First(gg => gg.Count() == 1).Select(r => r.Id).First();
    })
    .ToList();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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