2012-10-01 32 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; 
相關問題