c# - 将聚合函数作为参数传递

标签 c# linq lambda aggregate func

我有一个简单的对象:

public class Machine
{
    public string Name { get; set; }

    public int Power { get; set; }

    public int Type { get; set; }
}

然后有一个类包含这些对象的列表:

public class Aggregations
{
    private List<Machine> _machines;

    public Aggregations()
    {
        _machines = new List<Machine>
            {
                new Machine { Name = "XLR1", Power = 111, Type = 1 },
                new Machine { Name = "XLR2", Power = 222, Type = 1 },
                new Machine { Name = "XLR3", Power = 333, Type = 1 },
                new Machine { Name = "XLR4", Power = 444, Type = 1 },
                new Machine { Name = "XLR5", Power = 555, Type = 2 },
                new Machine { Name = "XLR6", Power = 666, Type = 2 }
            };           
    }
// ...
}

有两个函数可以返回具有特定条件的机器列表:

    public IEnumerable<Machine> MaxPower(IEnumerable<Machine> machines)
    {
        var maxPowerMachinesPerType = new List<Machine>();

        var groups = machines.GroupBy(m => m.Type);
        foreach (var g in groups)
        {
            var max = g.Max(m => m.Power);
            var machine = g.First(m => m.Power == max);
            maxPowerMachinesPerType.Add(machine);
        }

        return maxPowerMachinesPerType;
    }


    public IEnumerable<Machine> MinPower(IEnumerable<Machine> machines)
    {
        var minPowerMachinesPerType = new List<Machine>();

        var groups = machines.GroupBy(m => m.Type);
        foreach (var g in groups)
        {
            var min = g.Min(m => m.Power);
            var machine = g.First(m => m.Power == min);
            minPowerMachinesPerType.Add(machine);
        }

        return minPowerMachinesPerType;
    }
}

如您所见,这两个函数几乎相等。只有“最大”和“最小”不同。

这些函数是这样调用的:

IEnumerable<Machine> maxPowerMachines = MaxPower(_machines);
IEnumerable<Machine> minPowerMachines = MinPower(_machines);

因为我的实际程序稍微复杂一些,虽然我想调用其他聚合函数,但我想传递聚合函数作为参数:(伪代码)

IEnumerable<Machine> maxPowerMachines = SuperFunction(_machines, m => m.Max);
IEnumerable<Machine> minPowerMachines = SuperFunction(_machines, m => m.Min);
IEnumerable<Machine> averagePowerMachines = SuperFunction(_machines, m => m.Average);

我希望你明白了。

最佳答案

MinMax具有相同的签名,即它们都采用 IEnumerable<T>并产生 T ,你可以这样做:

public IEnumerable<Machine> SelectPower(
    IEnumerable<Machine> machines
,   Func<IEnumerable<int>,int> powerSelector
) {
    var res = new List<Machine>();
    var groups = machines.GroupBy(m => m.Type);
    foreach (var g in groups) {
        var targetPower =  powerSelector(g.Select(m => m.Power));
        var machine = g.First(m => m.Power == targetPower);
        res.Add(machine);
    }
    return res;
}

现在你可以这样调用你的方法了:

IEnumerable<Machine> maxPowerMachines = SuperFunction(_machines, m => m.Max());
IEnumerable<Machine> minPowerMachines = SuperFunction(_machines, m => m.Min());

关于c# - 将聚合函数作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35821300/

相关文章:

c# - Odata v4 web api 2.2 上下文当前未跟踪实体

c# - 使用C#连接MySQL Server 8.0

c# - 通过linq填充数据表

c# - 通过比较返回 lambda 表达式的扩展方法

c# - 我可以将 C# 字符串值转换为转义字符串文字吗?

c# - C#中字符串的快速哈希函数

c# - MVC中如何处理jQuery bootgrid请求数据

c# - 如何使用 LINQ 获取包含在多个列表中的元素列表?

python - 为什么 Python 描述符会复制?

python pandas 如果 A 列中有 1,则使用同一行中 B 列的值