我有一个对象列表(称它们为salesItems类型)。可以说这些项目有50个属性,其中Name,price,数量为3个。我想知道如何使用以下逻辑将列表合并在一起,按名称组合所有salesItems:

如果有多个具有相同名称的salesOrder:


将它们合并为一个具有相同名称的SalesOrder
将数量设置为数量的总和
使用第一个的值设置价格以及所有其他属性


我想用linq。我意识到我可以为每个c#循环使用较大的值。

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

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)



  结果列表我想要列表(A,C)中有2个销售订单A:名称=球价=
  2.24数量= 6(其他值=来自a的属性的bla bla)c:名称=蝙蝠价格= 22.14数量= 5(来自c的其他值
  属性)

最佳答案

您需要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类中添加一个构造函数(将其作为参数接受group by的结果)添加到类中,从而避免在linq查询中全部输入它们,然后执行所有工作在构造函数中。尽管它并不能阻止您键入所有属性,但这确实意味着它被巧妙地抽象了。同样,它也迫使/使您能够决定对每个属性(第一/总和/平均值)进行处理。

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

    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
    }


然后更新group by使其看起来像这样(请注意,现在仅将分组“ g”的结果传递到构造函数中):

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

10-07 20:47