【问题标题】:GroupBy item and Sum Quantities of itemsGroupBy item 和 Sum Quantities of items
【发布时间】:2018-01-25 00:22:07
【问题描述】:

我有一个订单数组,每个订单里面都是一个商品数组。如何按商品名称对所有订单进行分组并获取订购商品的总和。在这种情况下,输出将是:

输出

Item01 : quantity = 2;
Item02 : quantity = 45; 

获取订单

public Order[] GetOrders()
{
   Order[] orders = new Order[]
      {
         new Order
            {
               id = 1,
               orderLines = new OrderLine[]
                  {
                     new OrderLine
                        {
                           itemName = "Item 01",
                           quantity = 1
                        },
                     new OrderLine
                        {
                           itemName = "Item 02",
                           quantity = 3
                        },
                  },
            },
         new Order
            {
               id = 2,
               orderLines = new OrderLine[]
                  {
                     new OrderLine
                        {
                           itemName = "Item 01",
                           quantity = 1
                        },
                     new OrderLine
                        {
                           itemName = "Item 02",
                           quantity = 42
                        }
                  }
            }
      };
      ...

我尝试了以下方法:

foreach (var order in orders)
{
   foreach (var orderline in order.orderLines.GroupBy(x => x.itemName).Select(group => new
      {
         Metric = group.Key,
         Count = group.Count()
      }))

   {
      Console.WriteLine("{0} {1}", orderline.Metric, orderline.Count);
   }
} 

但它只为每个项目返回 1。我对编程比较陌生,所以请放轻松。谢谢

【问题讨论】:

  • 您必须以 SelectMany() 开头,才能将子列表扁平化为单个可枚举。然后你可以做你的分组等。

标签: c# arrays linq group-by count


【解决方案1】:

要获得所有订购商品的总和,请使用以下查询:

var results = 
    (from order in orders
    from orderLine in order.orderLines
    group orderLine by orderLine.itemName into orderLineGrouping
    let totalQuantity = orderLineGrouping.Sum(ol => ol.quantity)
    select new { itemName = orderLineGrouping.Key, metric = totalQuantity }).ToList();

results.ForEach(resultItem => Console.WriteLine("{0} {1}", resultItem.itemName, resultItem.metric);

【讨论】:

  • 这实际上并没有给我结果它给我的结果是“结果” System.Linq.Enumerable+WhereSelectEnumerableIterator2[System.Linq.IGrouping2[System.String,WarehouseOptimization.OrderLine],f__AnonymousType2`2 [System.String,System.Int32]]
  • 我已经编辑了答案,以确保它以与您在问题中尝试的方式相似的方式显示值。
  • 谢谢!!它适用于一个小的编辑。这是我的第一个问题,我立即得到了很好的答案。不确定我是否可以以 1 名声望回答这个问题。
【解决方案2】:
  1. 扁平化的订单线
  2. 为输出字符串分组项目名称和数量
  3. 使用分组键和分组数量之和选择输出字符串

见代码:

var output = orders.SelectMany(x => x.orderLines)
    .GroupBy(x => x.itemName, x => x.quantity)
    .Select(x => $"{x.Key} : quantity = {x.Sum(y => y)}");

【讨论】:

    【解决方案3】:

    扁平化OrderLines

    您需要熟悉Enumerable.SelectMany,它是最有用的方法之一

    SelectMany,来自 LINQ,将许多元素折叠成一个 收藏。结果集合是另一种元素类型。我们 指定如何将元素转换为其他元素的集合 元素。

    var summary = orders.Where(x => x.OrderLines != null) // Check for null as there seems to be null orderlines in your model
                        .SelectMany(x => x.OrderLines)  // Flatten
                        .GroupBy(x => x.itemName)       // Group
                        .Select(group => new            // Project
                                  {
                                     ItemName = group.Key,
                                     TotalQuantity = group.Sum(x => x.quantity)
                                  })
                        .ToList();                      // To List
    

    提示:为itemNamequantity 使用适当的大小写

    Capitalization Conventions

    下表总结了大写规则 标识符并提供不同类型的示例 标识符。

    对不起,我的 OCD 刚刚加入

    【讨论】:

    • .selectMany上有一个system.NullArguementexception
    • @AmetureBoss 这解决了你的问题吗?
    • @Surumen ,我认为您的意思是 Where(x => x.OrderLines != null) 而不是 Where(x => OrderLines != null)。
    • 我想我不清楚我需要添加数量,所以在这个前。项目 2 将是 45 而不是 2。您的答案将项目分组并添加单个项目的数量。
    猜你喜欢
    • 2020-12-18
    • 2022-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多