【问题标题】:LINQ suming nested groups in one statementLINQ 在一个语句中对嵌套组求和
【发布时间】:2011-10-04 12:16:12
【问题描述】:

我正在将一些代码转换为 LINQ,同时探索 LINQ 可以完成的程度。

能否将以下代码压缩为单个 LINQ 查询或方法?

Dictionary<string, ItemPack> consolidated = new Dictionary<string, ItemPack>();
foreach (var product in Products)
{
    foreach (var smallpack in product.ItemPacks)
    {
        ItemPack bigpack;
        if (consolidated.TryGetValue(smallpack.ItemCode, out bigpack))
        {
            // the big pack quantity += quantity for making one product * the number of that product
            bigpack.Quantity += smallpack.Quantity * product.Quantity;

            // References: we make sure that the small pack is using the Item in the big pack.
            // otherwise there will be 2 occurance of the same Item
            smallpack.Item = bigpack.Item;
        }
        else
        {
            bigpack = new ItemPack(smallpack); // Copy constructor
            bigpack.Quantity = smallpack.Quantity * product.Quantity;
            consolidated.Add(smallpack.ItemCode, bigpack);
        }
    }
}
return consolidated;

在英语中,每件商品都是由不同数量的几件商品组成的。这些项目按项目代码分组,并包装成小包装。这些小包装作为一个单元产品一起运输。有许多不同的产品。一个项目可以用于不同的产品。

我现在有一份产品清单和每个装运所需的数量。我想要一个 LINQ 语句来合并项目及其数量的平面列表。

我已经做到了这一点,但它似乎不起作用:

var packsQuery = from product in Products
                 from smallpack in product.ItemPacks
                 select new {Item = smallpack.Item, Quantity = smallpack.Quantity * product.Quantity};

foreach (var pack in packsQuery)
{
    consolidated.Add(pack.Item.ItemCode, new ItemPack(pack.Item, pack.Quantity));
}

如果我先分组,那么我无法选择项目的数量。如果我先选择,那么我将失去分组。鸡和蛋的故事?

编辑: 有用的说明:smallpack 是 ItemPack 类型,看起来像这样

public class ItemPack
{
     Item { get; } // The item in this pack, which *must* be a shared reference across all objects that uses this Item. So that change in Item properties are updated everywhere it is used. e.g. Price.
     ItemCode { get; } // The item code
     Quantity { get; } // The number of such Item in this pack.
}

【问题讨论】:

    标签: c# linq


    【解决方案1】:
        var query = (from product in Products
                    from smallPack in product.ItemPacks
                    select new
                    {
                        ItemCode = smallPack.ItemCode,
                        Item = smallPack.Item,
                        Quantity = smallPack.Quantity * product.Quantity,
                    })
                    .GroupBy(p => p.ItemCode)
                    .Select(p => new
                    {
                        ItemCode = p.Key,
                        Item = p.FirstOrDefault(),
                        Quantity = p.Sum(x=>x.Quantity)
                    })
                    .ToDictionary(p=>p.ItemCode);
    

    【讨论】:

      【解决方案2】:

      感谢您为我指明了正确的方向。我设法制定了完整的查询语法版本:

      var query = from product in Products
                  from smallpack in product.ItemPacks
                  select new {
                      Item = smallpack.Item,
                      Quantity = smallpack.Quantity * product.Quantity
                  } into mediumpack
                  group mediumpack by mediumpack.Item.ItemCode into bigpack
                  select new {
                      Item = bigpack.First().Item, // shared reference
                      Quantity = bigpack.Sum(a => a.Quantity);
                  }
      
      query.ToDictionary(...);
      

      关于这是否可以的任何问题?

      【讨论】:

      • 是的,这和我的一样,所以没问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多