patterncsharpMinor
Simple foreach adding to a list
Viewed 0 times
foreachlistsimpleadding
Problem
I am having a simple
Is there any way to do this with Linq with fewer lines?
foreach where I add objects to a list:List soonestDrawDateModel = new List();
foreach (var item in drawDates)
{
SoonestDrawDateModel sdModel = new SoonestDrawDateModel();
sdModel.DrawDay = item;
sdModel.DrawDayId = item.DayId;
sdModel.CutOffDayId = item.CutOffDayId;
soonestDrawDateModel.Add(sdModel);
sdModel = new SoonestDrawDateModel();
sdModel.DrawDayId = item.DayId + 7;
sdModel.CutOffDayId = item.CutOffDayId;
sdModel.DrawDay = item;
soonestDrawDateModel.Add(sdModel);
}
var realDrawDates = soonestDrawDateModel.OrderBy(x => x.DrawDayId);Is there any way to do this with Linq with fewer lines?
Solution
What you're doing here, essentially, is creating two Model items for each item in your source list, and storing them in a list. Here's a somewhat contrived usage of the SelectMany LINQ function which flattens a hierarchical list:
What we're doing here is creating a 2-item array or each Draw item, meaning we have an
You can simplify the syntax by extracting the main creation block into a method:
then call it with this LINQ call that conveys the intent rather well:
Or, as @anaximander suggests, an even terser (but less explicit) version that combines the Select and SelectMany calls. It saves a step, but it's less clear that we have two things going on - one to convert the DrawDate to two SoonestDrawDateModels, and another to flatten that list of lists.
drawDates
.Select(dd => new SoonestDrawDateModel[2] // create a 2-item array for each item.
{
new SoonestDrawDateModel
{
DrawDay = item,
DrawDayId = item.drawDayId,
CutOffDayId = item.CutOffDayId
},
new SoonestDrawDateModel
{
DrawDay = item,
DrawDayId = item.drawDayId + 7,
CutOffDayId = item.CutOffDayId
}
}) // end of Select method.
.SelectMany(items => items) // flatten collection of arrays into one collection.
.OrderBy(x => x.DrawDayId); // order by.
.ToList() //convert to a List.What we're doing here is creating a 2-item array or each Draw item, meaning we have an
IEnumerable, then use SelectMany to take all the members of each SoonestDrawDateModel[] and flatten them into one big IEnuemrable, which we then sort and return.You can simplify the syntax by extracting the main creation block into a method:
private SoonestDrawDateModel[] CreateDateModelPair(DrawItem item)
{
return new SoonestDrawDateModel[2]
{
new SoonestDrawDateModel
{
DrawDay = item,
DrawDayId = item.drawDayId,
CutOffDayId = item.CutOffDayId
},
new SoonestDrawDateModel
{
DrawDay = item,
DrawDayId = item.drawDayId + 7,
CutOffDayId = item.CutOffDayId
}
}
}then call it with this LINQ call that conveys the intent rather well:
drawDates
.Select(CreateDateModelPair)
.SelectMany (dateModels => dateModels)
.OrderBy (dateModel => dateModel.DrawDayId)
.ToList();Or, as @anaximander suggests, an even terser (but less explicit) version that combines the Select and SelectMany calls. It saves a step, but it's less clear that we have two things going on - one to convert the DrawDate to two SoonestDrawDateModels, and another to flatten that list of lists.
drawDates
.SelectMany (CreateDateModelPair)
.OrderBy (dateModel => dateModel.DrawDayId)
.ToList();Code Snippets
drawDates
.Select(dd => new SoonestDrawDateModel[2] // create a 2-item array for each item.
{
new SoonestDrawDateModel
{
DrawDay = item,
DrawDayId = item.drawDayId,
CutOffDayId = item.CutOffDayId
},
new SoonestDrawDateModel
{
DrawDay = item,
DrawDayId = item.drawDayId + 7,
CutOffDayId = item.CutOffDayId
}
}) // end of Select method.
.SelectMany(items => items) // flatten collection of arrays into one collection.
.OrderBy(x => x.DrawDayId); // order by.
.ToList() //convert to a List<SoonestDrawDateModel>.private SoonestDrawDateModel[] CreateDateModelPair(DrawItem item)
{
return new SoonestDrawDateModel[2]
{
new SoonestDrawDateModel
{
DrawDay = item,
DrawDayId = item.drawDayId,
CutOffDayId = item.CutOffDayId
},
new SoonestDrawDateModel
{
DrawDay = item,
DrawDayId = item.drawDayId + 7,
CutOffDayId = item.CutOffDayId
}
}
}drawDates
.Select(CreateDateModelPair)
.SelectMany (dateModels => dateModels)
.OrderBy (dateModel => dateModel.DrawDayId)
.ToList();drawDates
.SelectMany (CreateDateModelPair)
.OrderBy (dateModel => dateModel.DrawDayId)
.ToList();Context
StackExchange Code Review Q#111306, answer score: 5
Revisions (0)
No revisions yet.