I am converting some code to LINQ, at the same time exploring to what extent LINQ can accomplish.
Can the following code be condensed into a single LINQ query or method?
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;
In English, each product is made up of several items of different quantities. These items are grouped by item code and are packs into smallpacks. These smallpacks are shipped together as a unit product. There are many different products. A single item can be used in different product.
I now have a list of products and the quantity required for each for shipment. I want a LINQ statement to consolidate a flat list of items and their quantities.
I have gotten this far, but it looks like it does not work:
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));
}
If I group first, then I cannot select item for its quantity. If I select first, then I lose the grouping. Chicken and egg story?
EDIT:
Useful note: smallpack is of type ItemPack which looks like this
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.
}
1 Answer