如何从列表中填充缺失值

时间:2010-05-19 13:27:29

标签: linq

我有一个包含日期和计数的对象。

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

我有一个Serie对象,其中包含一些Stat和一些更多信息,例如名称等......

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

考虑一下我有一个系列列表,但系列并不都包含相同的邮票。 我需要使用默认值填写所有系列中丢失的邮票。

我想到了一个像这样的签名的扩展方法(如果找到一个,请提供更好的名称:)):

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

this question似乎对待同样的问题,但直接查询数据库时。当然,我可以遍历日期并创建另一个列表。但有没有更优雅的方法来实现这一目标?

即:

意甲:
01.05.2010 1
03.05.2010 3

乙级联赛:
01.05.2010 5
02.05.2010 6

我应该得到:

意甲:
01.05.2010 1
02.05.2010 0
03.05.2010 3

乙级联赛:
01.05.2010 5
02.05.2010 6
03.05.2010 0

1 个答案:

答案 0 :(得分:1)

不确定这是否足够优雅;-)但是因为我喜欢Linq,这就是我要做的(使用你的命名方案):

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))
        ));
}

要编译此代码,您的类需要几个构造函数:

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; }
}

调用series.Equalize(0)时,上面的代码将原始实例保持不变,并返回一系列新创建的Serie个实例,其Data用默认值填充。

没有什么神奇之处。只是Linq的甜蜜......(和空的合并运算符!)

我没有尝试过加载和加载数据,所以你的milage可能会有所不同。