I find myself repeating calculations within a linq statements and I was wondering whether I can access already computed elements somehow. This is what I m doing:
var result = testdata.GroupBy(a => new { a.reportinggroup, a.commodity, a.timestep.Year })
.Select(g => new EndResult
{
rundate = rundate.ToShortDateString(),
price = g.Sum(a => (a.timestep.ispeak()) ? a.price : 0) / g.Sum(a => (a.timestep.ispeak()) ? 1 : 0),
valueposition = g.Sum(a => (a.timestep.ispeak()) ? a.position * a.price : 0) / (g.Sum(a => (a.timestep.ispeak()) ? a.price : 0) / g.Sum(a => (a.timestep.ispeak()) ? 1 : 0)),
}).ToList();
Which works fine.
This is what I would like to be doing:
var result = testdata.GroupBy(a => new { a.reportinggroup, a.commodity, a.timestep.Year })
.Select(g => new EndResult
{
rundate = rundate.ToShortDateString(),
price = g.Sum(a => (a.timestep.ispeak()) ? a.price : 0) / g.Sum(a => (a.timestep.ispeak()) ? 1 : 0),
valueposition = g.Sum(a => (a.timestep.ispeak()) ? a.position * a.price : 0) / price,
}).ToList();
where the price is the price I computed just after rundate. Can I access this somehow?
You can select an anonymous type first to store this value:
result = testdata.GroupBy(a => new { a.reportinggroup, a.commodity, a.timestep.Year })
.Select(g => new {
rundate = rundate.ToShortDateString(),
price = g.Sum(a => (a.timestep.ispeak()) ? a.price : 0) / g.Sum(a => (a.timestep.ispeak()) ? 1 : 0),
group = g
})
.Select(x => new EndResult
{
rundate = x.rundate,
price = x.price,
valueposition = x.group.Sum(a => (a.timestep.ispeak()) ? a.position * x.price : 0) / x.price
}).ToList();
Another way is using "real" code:
result = testdata.GroupBy(a => new { a.reportinggroup, a.commodity, a.timestep.Year })
.Select(g => {
var price = g.Sum(a => (a.timestep.ispeak()) ? a.price : 0) / g.Sum(a => (a.timestep.ispeak()) ? 1 : 0);
EndResult endRes = new EndResult {
rundate = rundate.ToShortDateString(),
price = price,
valueposition = x.group.Sum(a => (a.timestep.ispeak()) ? a.position * price : 0) / price)
};
return endRes;
}).ToList();
By using the query syntax (from
), you can use the let clause:
var result = (from g in testdata.GroupBy(a => new { a.reportinggroup, a.commodity, a.timestep.Year })
let price = g.Sum(a => (a.timestep.ispeak()) ? a.price : 0) / g.Sum(a => (a.timestep.ispeak()) ? 1 : 0)
select new EndResult
{
rundate = rundate.ToShortDateString(),
price = price,
valueposition = g.Sum(a => (a.timestep.ispeak()) ? a.position * a.price : 0) / price,
}).ToList();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With