Lambda Max和Max and Max

时间:2012-06-11 19:24:46

标签: c# lambda

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

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

的那个
  • MAX(AverageRating)
  • 和Max(ReviewCount)
  • 和Max(NewestReviewDate)
  • 和Min(DistanceAway)

这样的事情:

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

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

当然,在多个陈述中,这很简单。

只是想知道这是否可能在一个声明中而不会破坏可读性。

提前谢谢你。我知道有些人喜欢查询问题!

5 个答案:

答案 0 :(得分:6)

你不能有多个最大值或分钟,这没有意义。 你需要某种启发式方法,如:

   .Max(x => x.AverageRating * x.ReviewCount - x.DaysSinceLastReview - x.DistanceAway)

答案 1 :(得分:6)

也许会这样做?

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

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

答案 2 :(得分: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

答案 3 :(得分: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查询中检索各种最大值和分钟会变得非常混乱,我也不确定效率是否有任何优势。

答案 4 :(得分: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();
}

我希望这能让你走上正轨。 :)