LINQ - 根据列表中的索引返回平均值列表

时间:2011-08-11 20:20:55

标签: .net linq list average

所以我有一个奇怪的场景,我无法理解我的头脑:

我有一个包含多个内部列表的外部列表。
每个内部列表包含多个DataPoint对象。
每个内部列表包含相同数量的DataPoint对象 数据点有一个名为Value的字段,它是一个双字符,例如:

  • Outerlist
    • Innerlist
      • 数据点(值= 2)
      • 数据点(值= 2)
    • Innerlist
      • 数据点(值= 4)
      • 数据点(值= 5)
    • Innerlist
      • 数据点(值= 3)
      • 数据点(值= 5)

所以我想做的是将内部列表“组合”到一个List中,其中每个DataPoint的值应该是旧值的平均值,基于列表中的索引 - 在这种情况下:

  • 列表
    • DataPoint(3) - ((2 + 4 + 3)/ 3)= 3
    • DataPoint(4) - ((2 + 5 + 5)/ 3)= 4

有没有任何整齐的linq表达可以执行这种东西(我打赌有:))?


我最终使用了以下解决方案:

var averages = Enumerable.Range(0,outer.First()。Count())。选择(i => new DataPoint(outer.Select(l => l [i])。Average(x = > x.Value)));

输出IEnumerable,现在平均价值 - yay!

4 个答案:

答案 0 :(得分:3)

从扩展方法开始,以获取内部列表的一部分:

public static IEnumerable<double> Slice(
    this IEnumerable<List<DataPoint>> innerLists,
    int index) {
        foreach(var innerList in innerLists) {
            yield return innerList.DataPoints[index].Value;
        }
    }
}

然后:

var averages = Enumerable.Range(0, count)
                         .Select(index => outerList.InnerLists.Slice(index))
                         .Select(slice => slice.Average());

我假设这样的层次结构:

class DataPoint { public double Value { get; set; } }

class InnerList { public List<DataPoint> DataPoints { get; set; } }

class OuterList { public IEnumerable<InnerList> InnerLists { get; set; } }

但是上述想法显然适应了你的数据结构。

答案 1 :(得分:2)

这里的关键是通过索引对内部列表值进行分组。像这样的东西会起作用:

// Test data
var list = new List<List<double>>() { 
    new List<double> { 2, 2 },
    new List<double> { 4, 5 },
    new List<double> { 3, 5 }
};

// Created groups based on index
var lookup = from inner in list 
             from value in inner.Select((n,idx) => new { n,idx })
             group value by value.idx;

// Calculate averages    
var averagesBasedOnIndex = lookup.Select(g => g.Average(x => x.n)).ToList();

答案 2 :(得分:1)

我在我的iPad上,所以我没有编译,但以下应该有效:

Enumerable.Range(0,outer.First().Length).
   Select(i => outer.Select(l => l[i]).Average());

答案 3 :(得分:0)

这就是你所需要的:

var outer = new List<List<List<double>>>();
var l1 = outer.Select(
  x => new List<double> { 
         x.Average(y => y[0]), 
         x.Average(y => y[1]), 
         x.Average(y => y[2])
       });

使用与您类似的数据结构,它将是:

var list = items.Select(x => new List<DataPoint> (
            Enumerable.Range(0,3).Select(z => 
                new DataPoint {
                   Value = x.InnerLists.Average(y => y.DataPoints[z].Value)})
           ));

(感谢任何人建议Enumerable.Range