Skip to main content
 首页 » 编程设计

c#之使用 linq 将集合中的项目合并在一起

2024年01月24日27lvdongjie

我有一个对象列表(将它们称为 salesItems 类型)假设这些项目有 50 个属性,名称、价格、数量是其中的 3 个)。我想知道如何使用以下逻辑将列表合并在一起,按名称组合任何 salesItems:

如果有多个具有相同名称的销售订单:

  • 将它们组合成一个同名的 SalesOrder
  • 将数量设置为数量的总和
  • 设置价格,并使用第一个值的所有其他属性

我想用 linq 来做。我意识到我可以为每个 c# 循环使用 big。

如果列表中还有其他项目,我也希望对这些项目遵循类似的逻辑。

EX:    A salesOrder list with (A,B,C,D,E) 
 
A: Name=ball  Price= 2.24  Quantity=1   (other values = bla bla) 
B: Name= ball  Price = 15.33  Quantity=3   (other values) 
c: Name= bat  Price = 22.14  Quantity=3    (other values) 
D: Name= bat Price= 19.22 Quantity=2    (other values) 
E: Name = ball Price=4.32 Quantity=2   (other values) 

Result list I want 2 Sales orders in list (A,C) A: Name=ball Price= 2.24 Quantity=6 (other values = bla bla from a's properties) c: Name= bat Price = 22.14 Quantity=5 (other values from c's properties)

请您参考如下方法:

你想要 linq 的 .GroupBy 方法!!!

我将你的类定义为:

public class SalesOrder 
{    
    public string Name { get; set; } 
    public double Price { get; set; } 
    public int Quantity { get; set; } 
 
    public SalesOrder(string Name, double Price, int Quantity) 
    { 
        this.Name = Name; 
        this.Price = Price; 
        this.Quantity = Quantity; 
    } 
} 

然后我创建了一个您的订单列表,如下所示:

List<SalesOrder> Orders = new List<SalesOrder>() 
{ 
    new SalesOrder("Ball", 2.24, 1), 
    new SalesOrder("Ball", 15.33, 3), 
    new SalesOrder("Bat", 22.14, 3), 
    new SalesOrder("Bat", 19.22, 2), 
    new SalesOrder("Ball", 4.32, 2) 
}; 

并按名称对它们进行分组,然后为每个组选择您想要的值并将其放入 SalesOrder 类的新实例中,如下所示:

List<SalesOrder> Combined_Orders = Orders 
    .GroupBy (o => o.Name) 
    .Select (o => new SalesOrder(o.Key, o.Select (x => x.Price).First(), o.Sum(x => x.Quantity))) 
    .ToList(); 

更新:回应 OP 的评论

由于真正的 SalesOrder 将有数百个属性,您可以通过向接受结果的 SalesOrder 类添加构造函数来避免在 linq 查询中将它们全部输入group by 作为参数,然后在构造函数中完成所有工作。虽然它不会阻止您输入所有属性,但这确实意味着它被巧妙地抽象掉了。同样,通过这种方式,它会强制/使您能够决定如何处理每个属性(第一个/求和/平均)。

为此,您需要第二个构造函数,如下所示:

    public SalesOrder(IGrouping<string, SalesOrder> Group) 
    { 
        this.Name = Group.Key; 
        this.Price = Group.First().Price; 
        this.Quantity = Group.Sum(g => g.Quantity); 
        // do all other properties here too 
    } 

然后更新分组依据如下(注意现在只有分组“g”的结果被传递到构造函数中):

List<SalesOrder> Combined_Orders = Orders 
    .GroupBy (o => o.Name) 
    .Select (g => new SalesOrder(g)) 
    .ToList();