2012-10-01 31 views
3
CustomClass{ 
int ID; 
int numberToSum; 
float numToAverage; 
} 


IEnumerable<CustomClass> results = MethodToPopulateIEnumerable(); 
List<int> listOfIDs = MethodToGetListOfIDs(); 

我想这些做的,就是把我的IEnumberable<CustomClass>并选择所有的人,其中ID是在List<int> listOfIDs,那么我想总结的numberToSum值并将其保存在变量中,并获取numToAverage属性的平均值并将其保存在变量中。总和项目与在IEnumerable的某些ID的自定义类

什么是最优雅的方式来做到这一点?

回答

7

我认为你正在寻找的东西是这样的:

IEnumerable<CustomClass> results = MethodToPopulateIEnumerable(); 
List<int> listOfIDs = MethodToGetListOfIDs(); 

查询语法

var query = from c in results 
      where listOfIds.Any(x => x == c.ID) 
      select c; 

方法语法

var query = results.Where(c => listOfIds.Any(x => x == c.ID)); 

Calcula蒸发散

int numberToSum = query.Sum(x => x.numberToSum); 
float numToAverage = query.Average(x => x.numToAverage); 

这将由其他成员allievate一些表演的担忧,但仍允许查询是另一种替代方法LINQ到任何友好(linq-to-entitieslinq-to-sql):

var calculations = (from c in results 
        where listOfIds.Any(x => x == c.ID) 
        group c by 1 into g 
        select new { 
        numberToSum = g.Sum(x => x.numberToSum), 
        numToAverage = g.Average(x => x.numToAverage),     
        }).FirstOrDefault(); 
+1

或许,如果'listOfIDs'或'results'是足够大的,可以考虑使用ID的'HashMap'代替,否则这可能是不必要的/慢迭代_a lot_利用。但除此之外,如果它们很小,那么它会很好地完成这项工作。 –

+1

@ChrisSinclair你的意思是'我假设HashSet'。 – Servy

+0

@Servy哎呀,是的。当我把它写下来时,我在想,它看起来不正确。 :) 谢谢。 –

1

我认为这是这样的:

var matchingIdsList = results.Where(x => listsOfIDs.Any(y => y == x.Id)); 
var sum = matchingIdsList.Sum(x=> x.numberToSum); 
var average = matchingIdsList.Average(x=> x.numToAverage); 
0

我会这样做 - 不是很优雅,但更有效率:

// Load IDs into a hashset so Contains is O(1) not O(n) 
var hashSetOfIDs = new HashSet<int>(listOfIDs); 

// Aggreagate count and both sums in one pass, then calculate average. 
var result = results.Where(cc => hashSetOfIDs.Contains(cc.ID)).Aggregate(
    new { Count = 0, Sum = 0, AverageSum = 0f }, 
    (a, cc) => new { 
     Count = a.Count + 1, 
     Sum = a.Sum + cc.numberToSum, 
     AverageSum = a.AverageSum + cc.numToAverage }, 
    a => new { 
     Sum = a.Sum, 
     Average = a.Count > 0 ? a.AverageSum/a.Count : float.NaN }); 

// Extract results 
var sum = result.Sum; 
var average = result.Average; 
0
var results = MethodToPopulateIEnumerable(); 
var listOfIDs = MethodToGetListOfIDs(); 

int numberToSum = 0; 
float numberToAverage = 0; 

var selected = results.Where(c => listOfIDs.Contains(c.ID)).Select(c => 
    { 
    numberToSum += c.numberToSum; 
    numberToAverage += c.numToAverage; 
    return c; 
    }).ToList(); 

float average = numberToAverage/selected.Count; 
相关问题