How to fill in missing values ​​from a list

I have an object that contains a date and a counter.

 public class Stat
 {
    public DateTime Stamp {get; set;}
    public int Count {get; set ;}
 }

      

I have a Serie object that contains a list of thoses Stat plus some additional information like name etc.

public class Serie
{
    public string Name { get; set; }
    public List<Stat> Data { get; set; }
    ...
}

      

Please note that I have a list of episodes, but not all the same stamps in the ranks. I need to fill in missing stamps in everything with default.

I was thinking about an extension method with a signature like this (please provide a better name if you find it :)):

 public static IEnumerable<Serie> Equalize(this IEnumerable<ChartSerie> series, int defaultCount)

      

this question seems to be referring to the same issue, but when querying the DB directly. of course, I could skip the dates and create another list. But is there a more elegant way to achieve this?

i.e:.

Series A:
05/01/2010 1
05/03/2010 3

Series B:
05/01/2010 5
05/02/2010 6

I have to get:

Series A:
05/01/2010 1
05/02/2010 0
05/03/2010 3

Series B:
05/01/2010 5
05/02/2010 6
05/03/2010 0

+2


a source to share


1 answer


Not sure if this is neat enough for you ;-), but since I like Linq, this is what I would do (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))
        ));
}

      

Your classes need several constructors to compile this code:

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 called series.Equalize(0)

, the above code will leave the original instances intact and return a sequence of newly created Serie

-instations with theirs Data

padded by default.

There is nothing magical about it. Just sweetness of Linq ... (and a null coalescing operator!)

I haven't tried this with loads and lots of data, so your movement may vary.

+1


a source







All Articles