将聚合函数作为参数传递
Pass aggregate function as parameter
我有一个简单的对象:
public class Machine
{
public string Name { get; set; }
public int Power { get; set; }
public int Type { get; set; }
}
然后有一个 class 包含这些对象的列表:
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 }
};
}
// ...
}
有两个函数 return 列出具有特定条件的机器:
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;
}
}
如您所见,这两个函数几乎相等。只有 "max" 和 "min" 不同。
这些函数是这样调用的:
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);
我希望你明白了。
Func<T>
听起来像您要找的东西。前导类型 <T>
显示输入,最后一个 <T>
显示 return 值,所以你会寻找这样的东西:
Func<IEnumerable<Machine>, IEnumerable<Machine>> aggregateFunction = MaxPower;
//Now you can pass aggregateFunction around as a variable. You can call it like so:
var machines = Aggregations();
aggregateFunction.Invoke(machines);
由于 Min
和 Max
具有相同的签名,即它们都采用 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());
我有一个简单的对象:
public class Machine
{
public string Name { get; set; }
public int Power { get; set; }
public int Type { get; set; }
}
然后有一个 class 包含这些对象的列表:
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 }
};
}
// ...
}
有两个函数 return 列出具有特定条件的机器:
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;
}
}
如您所见,这两个函数几乎相等。只有 "max" 和 "min" 不同。
这些函数是这样调用的:
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);
我希望你明白了。
Func<T>
听起来像您要找的东西。前导类型 <T>
显示输入,最后一个 <T>
显示 return 值,所以你会寻找这样的东西:
Func<IEnumerable<Machine>, IEnumerable<Machine>> aggregateFunction = MaxPower;
//Now you can pass aggregateFunction around as a variable. You can call it like so:
var machines = Aggregations();
aggregateFunction.Invoke(machines);
由于 Min
和 Max
具有相同的签名,即它们都采用 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());