LINQ中如何实现“搜索并取最佳”的功能?

7

你好!

我正在寻找一种方法来搜索一个集合,以找到最符合我的标准的对象。由于我经常这么做,所以我在研究如何使用LINQ执行查询,但是没有找到一种简单的方法来执行此操作,而不浪费时间。

一个功能实现可能是:

collection.OrderByDescending(f => FitFunction(f)).First()

但这似乎不必要地进行了排序。我只需要线性扫描就可以了。Min LINQ函数返回最佳匹配,而不是产生最佳匹配的对象,因此似乎并不有用。

为了清晰起见,我通常会写非LINQ代码(我已经这样做了很多次):

T best;
float bestFit = something very low;

foreach (T ob in collection)
{
  float fit = FitFunction(ob);
  if (fit > bestFit)
  {
    bestFit = fit;
    best = ob;
  }
}
return best;

我认为我可以自己创建一个扩展方法来实现这个功能;但是在LINQ中一定已经有一种方法可以做到这一点。

谢谢!


ob对象传递给FitFunction不如将FitFunction的结果作为ob属性,从而使collection.Min(t => t.FitValue)可用。 - vlad
@vlad:不幸的是,Enumerable.Min()方法返回最小值投影...而不是对象实例t,这正是OP所寻找的。这就是为什么MoreLINQ引入了MinBy和MaxBy运算符的原因。 - LBushkin
困难在于Min函数将产生t.FitValue,而不是t。除此之外,这将必然地将FitValue与对象绑定在一起,为了保持代码松散耦合,我会避免这种情况。 - Nick Gebbie
(顺便感谢 bdukes 的格式帮助) - Nick Gebbie
1个回答

7
这本质上是一个基于谓词的Top-N问题,其中额外的限制条件是N始终等于1。不幸的是,没有内置的LINQ运算符执行TopN()操作...但正如你所指出的那样,自己编写一个也不太难。 MoreLINQ库有一个MaxBy()运算符的实现,它允许您指定一个谓词,并且也可以使用。

Reactive Extensions (Rx)附带的System.Interactive程序集也有MaxBy的实现。http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx - bdukes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接