如何使用linq在单一方法中使聚合函数? [英] How to make aggregate function in single method using linq?

查看:89
本文介绍了如何使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆