How to Sum using lambda expression

I'm attempting to Sum the cost of all the parts int a group.

My Total, TotalLength, Loss, and CutPart work as expected.

When I Sum the cost for all the parts in the group I'm not getting the expected results.

Everything calculates perfectly but not the Sum / Cost

--Here is where I'm grouping

 List<PartsProcessor.IPart> parts = Task.Run(async () => await this.ProcessedParts.CombineParts(false)).Result;

//Stocks
this.StockLengths = parts.GroupBy(o => new { o.PartNumber, o.StockLength }).Select(g => new PartsProcessor.GroupedPart
{
    Total = (g.Key.StockLength > 0 ? int.Parse((Math.Ceiling(g.Sum(s => s.Length) / (g.Key.StockLength))).ToString()) : 1),
    TotalLength = g.Sum(s => s.Length),
    Loss = g.Key.StockLength > 0 ? (g.Key.StockLength * (Math.Ceiling(g.Sum(s => s.Length) / (g.Key.StockLength)))) - (g.Sum(s => s.Length)) : 0,
    **Cost = g.Sum(s => s.Cost),**
    CutPart = g.FirstOrDefault()
}
                                     )
.Where(w => w.CutPart.Category.ToLower() != "glass" &&
            w.CutPart.Category.ToLower() != "glazing" &&
           !w.CutPart.Category.ToLower().Contains("epdm") &&
           !w.CutPart.Category.ToLower().Contains("end dam") &&
            w.CutPart.Category.ToLower() != "leaf" &&
            w.CutPart.Category.ToLower() != "door frame").ToList<PartsProcessor.IGroupedPart>();

--Properties in debug mode

In the two snap shots below it shows the Cost for each, Total parts needed, and the total Cost. But the total cost is not correct.

Where am I going wrong here?

Snap 1

Snap 2

Snap 3, 1 and 2 combined

Upvotes: 3

Views: 12128

Answers (2)

usr
usr

Reputation: 171178

Responsding to your request from the comments I provide the following snippet:

from w in parts
where Filter(w)
group w by new { w.PartNumber, w.StockLength } into g
let someValue = int.Parse((Math.Ceiling(g.Sum(s => s.Length)/(g.Key.StockLength))).ToString())
select new
{
    Total = g.Key.StockLength > 0 ? someValue : 1,
    TotalLength = g.Sum(s => s.Length),
    Loss = g.Key.StockLength > 0 ? someValue - (g.Sum(s => s.Length)) : 0,
    Cost = (g.Key.StockLength > 0 ? someValue : 1)*g.Average(s => s.Cost),
    CutPart = g.FirstOrDefault(),
};

You can reuse someValue as often as you want.

Upvotes: 4

I got it to work with the code below. Moving the where and groupby didn't help. Since the average is always going to be the same I was able to write the code like I have below.

 this.StockLengths = parts
                     .Where(w => w.Category.ToLower() != "glass" &&
                            w.Category.ToLower() != "glazing" &&
                           !w.Category.ToLower().Contains("epdm") &&
                           !w.Category.ToLower().Contains("end dam") &&
                            w.Category.ToLower() != "leaf" &&
                            w.Category.ToLower() != "door frame")

                    .GroupBy(o => new { o.PartNumber, o.StockLength }).Select(g => new PartsProcessor.GroupedPart
                {
                    Total = (g.Key.StockLength > 0 ? int.Parse((Math.Ceiling(g.Sum(s => s.Length) / (g.Key.StockLength))).ToString()) : 1),
                    TotalLength = g.Sum(s => s.Length),
                    Loss = g.Key.StockLength > 0 ? (g.Key.StockLength * (Math.Ceiling(g.Sum(s => s.Length) / (g.Key.StockLength)))) - (g.Sum(s => s.Length)) : 0,
                    Cost = (g.Key.StockLength > 0 ? int.Parse((Math.Ceiling(g.Sum(s => s.Length) / (g.Key.StockLength))).ToString()) : 1) * g.Average(s => s.Cost),
                    CutPart = g.FirstOrDefault()
                }
                  ).ToList<PartsProcessor.IGroupedPart>();

Upvotes: 2

Related Questions