我有两种方法,唯一的区别是一个lambda谓词:
public static double LowerQuartile(this IOrderedEnumerable<double> list)
{
var median = list.Median();
var elements = list.Where(x => x < median).ToList();
if (!list.Contains(median))
elements.Add(median);
return elements.OrderBy(x => x).Median();
}
public static double UpperQuartile(this IOrderedEnumerable<double> list)
{
var median = list.Median();
var elements = list.Where(x => x > median).ToList();
if (!list.Contains(median))
elements.Add(median);
return elements.OrderBy(x => x).Median();
}
所以我想加入它们并传递一个lambda作为参数。我试过这样的事情:
public static double CalculateQuartile(IOrderedEnumerable<double> list, Expression<Func<IOrderedEnumerable<double>,bool>> predicate)
{
var median = list.Median();
var elements = list.Where(predicate).ToList();
if (!list.Contains(median))
elements.Add(median);
return elements.OrderBy(x => x).Median();
}
但它不起作用。我怎么能这样做?
答案 0 :(得分:3)
可能是这样的
public static double Quartile(this IOrderedEnumerable<double> list,
Func<double,double,bool> predicate)
{
var median = list.Median();
var elements = list.Where(x=>predicate(x,median)).ToList();
if (!list.Contains(median))
elements.Add(median);
return elements.OrderBy(x => x).Median();
}
您可以使用
var val = list.Quartile((x, y) => x > y);
答案 1 :(得分:2)
lambdas x => x < median
和x => x > median
都属于Func<double, bool>
类型。正如您将median
作为另一个变量,你必须接受它作为参数,所以最终会得到Func<double, double, bool>
:
public static double CalculateQuartile(this IOrderedEnumerable<double> list,
Func<double, double, bool> predicate)
{ … }
你可以将其作为表达式执行,并在运行时粘贴到median
的引用中,但我建议不要这样做。
相反,我建议你以某种方式解决这个问题,你的函数用户不需要为它指定正确的lambda。毕竟,你只有两个案例:上四分位数和下四分位数。所以你可能只想让一个布尔标志作为一个参数,它允许你选择较低的上四分位数:
public static double CalculateQuartile(this IOrderedEnumerable<double> list,
bool calculateUpperQuartile = false)
{
var median = list.Median();
var predicate = calculateUpperQuartile ? (x => x > median) : (x => x < median);
var elements = list.Where(predicate).ToList();
if (!list.Contains(median))
elements.Add(median);
return elements.OrderBy(x => x).Median();
}
为了让用户更容易使用它,我仍然会提供CalculateUpperQuartile
和CalculateLowerQuartile
功能 - 但是当然,你可以在内部使用单个实现来处理它们。