首页 > 解决方案 > 比较两个对象列表并修改属性

问题描述

我正在尝试比较两个对象列表并从中创建一个全新的列表。

我有一个名为 Item 的类。

public class Item
{
    public string ItemNumber;
    public string OptionNumber;
    public int Count;
}

我有两个项目列表 - 已处理项目和当前项目。

List<Item> processedItems = new List<Item>();  
List<Item> currentItems = new List<Item>();

我想要一个已处理项目的列表。

但是,如果在 currentItems 中存在 ItemNumber 和 OptionNumber,我希望 Count 属性是两个值的总和(processedItems 和 currentItems 中的值)。

示例预期值和实际值。

processedItems.Add(new Item() { ItemNumber = "123456", OptionNumber = "123", Count = 1 });
processedItems.Add(new Item() { ItemNumber = "123456", OptionNumber = "126", Count = 2 });
processedItems.Add(new Item() { ItemNumber = "112233", OptionNumber = "111", Count = 1 });
processedItems.Add(new Item() { ItemNumber = "112244", OptionNumber = "222", Count = 4 });

currentItems.Add(new Item() { ItemNumber = "123456", OptionNumber = "123", Count = 1 });
currentItems.Add(new Item() { ItemNumber = "123456", OptionNumber = "126", Count = 2 });
currentItems.Add(new Item() { ItemNumber = "998877", OptionNumber = "111", Count = 1 });
currentItems.Add(new Item() { ItemNumber = "112244", OptionNumber = "222", Count = 0 });

从上面的例子中,我试图得到以下输出:

List<Item> output = new List<Item>();

output.Add(new Item() { ItemNumber = "123456", OptionNumber = "123", Count = 2 });
output.Add(new Item() { ItemNumber = "123456", OptionNumber = "126", Count = 4 });
output.Add(new Item() { ItemNumber = "112233", OptionNumber = "111", Count = 1 });
output.Add(new Item() { ItemNumber = "112244", OptionNumber = "222", Count = 4 });

我需要使用 Concat 吗?我目前有这样的东西

var output = processedItems.Select(x => new Item
{
    ItemNumber = x.ItemNumber,
    OptionValue = x.OptionValue,
    Count = x.Count + (currentItems.FirstOrDefault(y => y.ItemNumber == x.ItemNumber && y.OptionValue == x.OptionValue).Count)
}).Concat(currentItems
    .Where(x => processedItems.Any(y => y.ItemNumber == x.ItemNumber && y.OptionValue == x.OptionValue)))
    .Select(x => new Item
    {
        ItemNumber = x.ItemNumber,
        OptionValue = x.OptionValue,
        Count = x.Count
    })
    .ToList();

标签: c#linq

解决方案


您可以使用GroupJoin,并从 中选择元素,仅processedItems使用连接元素之间的of ,如以下代码:currentItemssumcount

var output =
    processedItems
        .GroupJoin(
            currentItems,
            prd => new { prd.ItemNumber, prd.OptionNumber },
            sel => new { sel.ItemNumber, sel.OptionNumber },
            (prd, sel) => new Item
            {
                ItemNumber = prd.ItemNumber,
                OptionNumber = prd.OptionNumber,
                Count = sel.Sum(s => s.Count) + prd.Count
            })
        .ToList();

演示

foreach (Item item in output)
{
    Console.WriteLine($"ItemNumber:{item.ItemNumber}, OptionNumber:{item.OptionNumber}, Count:{item.Count}");
}

结果

ItemNumber:123456, OptionNumber:123, Count:2
ItemNumber:123456, OptionNumber:126, Count:4
ItemNumber:112233, OptionNumber:111, Count:1
ItemNumber:112244, OptionNumber:222, Count:4

我希望这可以帮助您解决问题。


推荐阅读