C# 对自定义类的IEnumerable中具有特定ID的项求和 CustomClass{ int-ID; 整数和; 浮动平均数; } IEnumerable results=MethodTopopulateEnumerable(); List listOfIDs=MethodToGetListOfIDs();
我想要做的是,取我的C# 对自定义类的IEnumerable中具有特定ID的项求和 CustomClass{ int-ID; 整数和; 浮动平均数; } IEnumerable results=MethodTopopulateEnumerable(); List listOfIDs=MethodToGetListOfIDs();,c#,.net,linq,list,ienumerable,C#,.net,Linq,List,Ienumerable,我想要做的是,取我的IEnumberable并选择ID位于列表ID中的所有ID,然后我想要对该ID的numberToSum值求和,并将其保存在变量中,得到numToAverage属性的平均值,并将其保存在变量中 做这件事最优雅的方式是什么?我想你正在寻找这样的方式: CustomClass{ int ID; int numberToSum; float numToAverage; } IEnumerable<CustomClass> results = MethodToPopul
IEnumberable
并选择ID位于列表ID
中的所有ID,然后我想要对该ID的numberToSum
值求和,并将其保存在变量中,得到numToAverage
属性的平均值,并将其保存在变量中
做这件事最优雅的方式是什么?我想你正在寻找这样的方式:
CustomClass{
int ID;
int numberToSum;
float numToAverage;
}
IEnumerable<CustomClass> results = MethodToPopulateIEnumerable();
List<int> listOfIDs = MethodToGetListOfIDs();
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();
方法语法
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));
另一种替代方法将评估其他成员的一些性能问题,但仍然允许查询对任何友好的对象都是linq(linq to entities
,linq to sql
):
我想是这样的:
CustomClass{
int ID;
int numberToSum;
float numToAverage;
}
IEnumerable<CustomClass> results = MethodToPopulateIEnumerable();
List<int> listOfIDs = MethodToGetListOfIDs();
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();
我会这样做——不是很优雅,但效率更高:
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);
//将ID加载到哈希集中,使其包含的是O(1)而不是O(n)
var hashSetOfIDs=新HashSet(listOfIDs);
//一次累计计数和两个总和,然后计算平均值。
var result=results.Where(cc=>hashSetOfIDs.Contains(cc.ID)).Aggregate(
新{Count=0,Sum=0,AverageSum=0f},
(a,cc)=>新{
计数=a。计数+1,
Sum=a.Sum+cc.numberToSum,
AverageSum=a.AverageSum+cc.numToAverage},
a=>新{
Sum=a.Sum,
平均值=a.计数>0?a.平均值总和/a.计数:float.NaN});
//提取结果
var sum=result.sum;
var平均值=结果平均值;
<代码> >如果<代码> Listopid 或结果 足够大,考虑使用IDS代码> HashMap <代码> IDS,否则可能会有很多不必要的/慢的迭代。但是,如果它们很小,那就很好了。@ChrisSinclair你的意思是HashSet
我猜。@Servy-Oops,是的。当我把它写下来时,我在想它似乎不对谢谢
// 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;
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;