使用linq将项目合并在一个集合中

jvo*_*igt 1 c# linq collections

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

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

  • 将它们组合到一个具有相同名称的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)
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*Ben 7

你想要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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个这样的订单列表:

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)
};
Run Code Online (Sandbox Code Playgroud)

并在为每个组选择所需的值之前按名称对它们进行分组,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();
Run Code Online (Sandbox Code Playgroud)

更新:回应OP的评论

由于真实SalesOrder将有数百个属性,你可以避免在linq查询中输入所有内容,方法是将一个构造函数添加到SalesOrder接受组的结果作为参数的类中,然后在构造函数中完成所有工作.虽然它不会阻止你输入所有的属性,但它确实意味着它整齐地抽象了.同样,这会强制/使您能够决定如何处理每个属性(第一个/总和/平均值).

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

    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
    }
Run Code Online (Sandbox Code Playgroud)

然后更新组看起来像这样(请注意,现在只将分组"g"的结果传递给构造函数):

List<SalesOrder> Combined_Orders = Orders
    .GroupBy (o => o.Name)
    .Select (g => new SalesOrder(g))
    .ToList();
Run Code Online (Sandbox Code Playgroud)

  • 很抱歉看到这个答案未被接受。构造器部分是一个绝妙的解决方案。 (2认同)