Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对自定义类的IEnumerable中具有特定ID的项求和 CustomClass{ int-ID; 整数和; 浮动平均数; } IEnumerable results=MethodTopopulateEnumerable(); List listOfIDs=MethodToGetListOfIDs();_C#_.net_Linq_List_Ienumerable - Fatal编程技术网

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;