how to fill missing values from a list
I have an object containing a date and a count.
public class Stat
{
public DateTime Stamp {get; set;}
public int Count {get; set ;}
}
I have a Serie object that holds a list of thoses Stat plus some more info such as name and so on...
public class Serie
{
public string Name { get; set; }
public List<Stat> Data { get; set; }
...
}
Consider that I have a List of Serie but the series don't all contain the same Stamps. I need to fill in the missing stamps in all series with a default value.
I thought of an extension method with signature like this (please provide better name if you find one :) ) :
public static IEnumerable<Serie> Equalize(this IEnumerable<ChartSerie> series, int defaultCount)
this question seems to treat the same problem, but when querying directly the DB. of course I could 开发者_运维问答loop through the dates and create another list. But is there any more elegant way to achieve this?
i.e.:
Serie A:
01.05.2010 1 03.05.2010 3Serie B:
01.05.2010 5 02.05.2010 6I should get :
Serie A :
01.05.2010 1 02.05.2010 0 03.05.2010 3Serie B:
01.05.2010 5 02.05.2010 6 03.05.2010 0Not sure if this is elegant enough for you ;-) but since I like Linq, this is what I would have done (using your naming scheme):
public static IEnumerable<Serie> Equalize(
this IEnumerable<Serie> series,
int defaultCount)
{
var allStamps = series
.SelectMany(s => s.Data.Select(d => d.Stamp))
.Distinct()
.OrderBy(d => d)
.ToList();
return series.Select(serie => new Serie(
serie.Name,
allStamps.Select(d =>
serie.Data.FirstOrDefault(stat => stat.Stamp == d)
??
new Stat(d, defaultCount))
));
}
For this code to compile, your classes needs a couple of constructors:
public class Stat
{
public Stat() {}
public Stat(DateTime stamp, int count)
{
Stamp = stamp;
Count = count;
}
public DateTime Stamp { get; set; }
public int Count { get; set; }
}
public class Serie
{
public Serie() {}
public Serie(string name, IEnumerable<Stat> data)
{
Name = name;
Data = new List<Stat>(data);
}
public string Name { get; set; }
public List<Stat> Data { get; set; }
}
When calling series.Equalize(0)
the code above will leave the original instances intact, and return a sequence of newly created Serie
-instances with their Data
padded with defaults.
Nothing magic about it. Just the sweetness of Linq... (and the null coalescing operator!)
I haven't tried this with loads and loads of data, so your milage may vary.
精彩评论