开发者

how to fill missing values from a list

开发者 https://www.devze.com 2022-12-31 01:43 出处:网络
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 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 3

Serie B:

01.05.2010 5

02.05.2010 6

I should get :

Serie A :

01.05.2010 1

02.05.2010 0

03.05.2010 3

Serie B:

01.05.2010 5

02.05.2010 6

03.05.2010 0


Not 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号