如何使用linq在单一方法中使聚合函数? [英] How to make aggregate function in single method using linq?
问题描述
我有这样的课
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public GRADE Grade { get; set; }
public string Nationality { get; set; }
}
public enum GRADE
{
A = 0,
B = 1,
C = 2,
D = 3,
E = 4
}
var list = new List<Student>();
list.Add(new Student() { Id = 1, Name = "Prasad", Gender = "M", Nationality = "India", Grade = GRADE.A });
list.Add(new Student() { Id = 2, Name = "Raja", Gender = "M", Nationality = "India", Grade = GRADE.B });
list.Add(new Student() { Id = 3, Name = "Hindu", Gender = "F", Nationality = "India", Grade = GRADE.A });
list.Add(new Student() { Id = 4, Name = "Hamed", Gender = "M", Nationality = "India", Grade = GRADE.C });
list.Add(new Student() { Id = 5, Name = "Priya", Gender = "F", Nationality = "India", Grade = GRADE.D });
list.Add(new Student() { Id = 6, Name = "Meera", Gender = "F", Nationality = "India", Grade = GRADE.B });
我得到了这样的解决方案,我想为每个表达式写一堆代码.Sum,Avg,Count等
I got the solution like this, For each expression i want to write bunch of code.. Sum,Avg,Count etc
Linq表达式
//count
var c = (from x in list.GroupBy(k => k.Gender)
select new
{
category = x.Key,
Value = x.Count()
}).ToList();
//sum
var s = (from x in list.GroupBy(k => k.Gender)
select new
{
category = x.Key,
Value = x.Sum(k => (int)k.Grade)
}).ToList();
//avg
var a = (from x in list.GroupBy(k => k.Gender)
select new
{
category = x.Key,
Value = x.Average(k => (int)k.Grade)
}).ToList();
我正在尝试基于聚合函数来创建一个函数;它应该返回值,我试图找不到它.
I am trying to make one function, based on the aggregate function; it should return the value, I tried I could not find it.
推荐答案
您遇到的一个问题是,所有三个集合都不具有相同的返回类型,如果使用函数,则该返回类型也必须是对象,因为您返回的是匿名类型.
One issue you have is that all three aggregates do not have the same return type, also if you use a function then the return type would have to be object because you are returning an anonymous type.
我能找到我想得到的最接近的东西是
The closest I could get to what I think you want was this;
第1步:创建新类型;
Step 1: create a new type;
public class AggregateValue<T>
{
public string Category { get; set; }
public T Value { get; set; }
}
第2步:创建一个返回此类型集合并接受Func作为参数的函数,该函数将计算您的不同聚合;
Step 2: Create a function that returns a collection of this type and accepts a Func as a parameter that will calculate your different aggregates;
IEnumerable<AggregateValue<T>> GetAggregateValues<T>(List<Student> students, Func<IEnumerable<Student>, T> aggregateFunction)
{
return (from x in students.GroupBy(k => k.Gender)
select new AggregateValue<T>
{
Category = x.Key,
Value = aggregateFunction(x)
}).ToList();
}
您可以像这样使用它;
You can use it like this;
var list = new List<Student>();
list.Add(new Student() { Id = 1, Name = "Prasad", Gender = "M", Nationality = "India", Grade = GRADE.A });
list.Add(new Student() { Id = 2, Name = "Raja", Gender = "M", Nationality = "India", Grade = GRADE.B });
list.Add(new Student() { Id = 3, Name = "Hindu", Gender = "F", Nationality = "India", Grade = GRADE.A });
list.Add(new Student() { Id = 4, Name = "Hamed", Gender = "M", Nationality = "India", Grade = GRADE.C });
list.Add(new Student() { Id = 5, Name = "Priya", Gender = "F", Nationality = "India", Grade = GRADE.D });
list.Add(new Student() { Id = 6, Name = "Meera", Gender = "F", Nationality = "India", Grade = GRADE.B });
var sumGrades = new Func<IEnumerable<Student>, int>(p => p.Sum(l => (int)l.Grade));
var aveGrades = new Func<IEnumerable<Student>, double>(p => p.Average(k => (int)k.Grade));
var count = new Func<IEnumerable<Student>, int>(p => p.Count());
var c = GetAggregateValues(list, count);
var s = GetAggregateValues(list, sumGrades);
var a = GetAggregateValues(list, aveGrades);
这篇关于如何使用linq在单一方法中使聚合函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!