3

快速且可能很简单的 Lambda 问题:

我有一家有评论的餐厅。我想查询一个:

  • 最大(平均评分)
  • 和 Max(ReviewCount)
  • 和最大(NewestReviewDate)
  • 和最小(距离)

像这样的东西:

var _Result = AllRestaurants
    .Max(x => x.AverageRating)
    .AndMax(x => x.ReviewCount)
    .AndMax(x => x.NewestReviewDate)
    .AndMin(x => x.DistanceAway);

现在,我知道那是伪代码。但它完美地描述了它!

当然,在多个语句中,这很简单。

只是想知道这是否可能在一个语句中而不会降低可读性。

先感谢您。我知道你们中的一些人喜欢查询问题!

4

5 回答 5

6

你不能有多个最大值或最小值,这是没有意义的。您将需要某种启发式方法,例如:

   .Max(x => x.AverageRating * x.ReviewCount - x.DaysSinceLastReview - x.DistanceAway)
于 2012-06-11T19:30:37.317 回答
6

也许这会做?

var bestRestaurant = AllRestaurants
    .OrderByDescending(r => r.AverageRating)
    .ThenByDescending(r => r.ReviewCount)
    .ThenByDescending(r => r.NewestReviewCount)
    .ThenBy(r => r.DistanceAway)
    .FirstOrDefault();

您需要更改语句的顺序以反映哪个是最重要的。

于 2012-06-11T19:38:17.960 回答
1

有一些加权启发式的替代方法是按 AverageRating 排序,然后是 ReviewCount,然后...

像这样的东西应该工作:

var _Result = AllRestaurants
    .OrderByDescending(x => x.AverageRating)
    .ThenByDescending(x => x.ReviewCount)
    .ThenByDescending(x => x.NewestReviewDate)
    .ThenByDescending(x => x.DistanceAway);
    // using *Descending so you get the higer-valued ones first
于 2012-06-11T19:42:54.590 回答
0

如果我理解你的问题,我认为最好的方法是写你提到的个人陈述......

var HighestRating = AllRestaurants.Max(x => x.AverageRating);
var HighestReviewCount = AllRestaurants.Max(x => x.ReviewCount);
var LatestReviewDate = AllRestaurants.Max(x => x.NewestReviewDate);
var ShortestDistanceAway = AllRestaurants.Min(x => x.DistanceAway);

从单个 Linq 查询中检索各种最大值和最小值会变得非常混乱,我也不确定效率是否有任何优势。

于 2012-06-11T19:39:02.907 回答
0

考虑这样的事情......

List<RestaurantRecord> _Restaurants;

public RestaurantRecord Best()
{
    return _Restaurants.Where(
               x =>
                   x.AverageRating >= _BestRating &&
                   x.ReviewCount >= _MinReviews &&
                   x.Distance <= _MaxDistance)
                       .GetFirstOrDefault();
}

话虽如此,在这种情况下使用 lambda 将在未来产生可维护性后果。重构它是一个好主意,这样如果将来出现其他标准(例如:智能手机访问?美食类型?),您的应用程序可以更容易地修改以适应这些标准。

关于这一点,一个稍微好一点的实现可能是这样的:

public RestaurantRecord Best()
{
    IQueryable temp = _Restaurants.Clone();

    temp = temp.Where( x => x.AverageRating >= _BestRating );
    temp = temp.Where( x => x.ReviewCount >= _MinReviews );
    // ...snip...

    return temp.GetFirstOrDefault();
}

我希望这能让你走上正确的道路。:)

于 2012-06-11T19:40:38.240 回答