【问题标题】:Find least Rate in a List<T> in a specific group在特定组中的 List<T> 中查找最低速率
【发布时间】:2016-07-15 21:09:43
【问题描述】:

我有 List finalReportDetails,它包含同一个 WebsiteId 和 CheckInDate 的多个费率。 对于每个 websiteId 和 checkindate,我只需要一个记录。 此记录应具有最低的速率(第一偏好)或速率 -1。 应该从列表中删除该组的所有记录。

初始列表

 List<Rates> rates = new List<Rates>()
    {
        new Rates { CheckInDate = timeValue, websiteId = 1, price = 1 },
        new Rates { CheckInDate = timeValue, websiteId = 1, price = 2 },
        new Rates { CheckInDate = timeValue, websiteId = 2, price = -1 },
        new Rates { CheckInDate = timeValue, websiteId = 2, price = 2 },
        new Rates { CheckInDate = timeValue, websiteId = 3, price = -1 },
        new Rates { CheckInDate = timeValue, websiteId = 3, price = -1 },
    };

最终名单

List<Rates> rates = new List<Rates>()
        {
            new Rates { CheckInDate = timeValue, websiteId = 1, price = 1 },
            new Rates { CheckInDate = timeValue, websiteId = 2, price = 2 },
            new Rates { CheckInDate = timeValue, websiteId = 3, price = -1 },
        };

我已经尝试过这段代码,但是遍历循环需要很多时间。 首先,我通过 CheckInDate、WebsiteId 找到了不同的组。 然后对于每个组,我正在检查所需的费率。

    class Rates {
    public int websiteId {get; set;},
    public DateTime CheckInDate {get; set;}
    public decimal price {get; set;}}


var grouped = (from s in finalReportDetails
                           select new { s.CheckInDate,s.websiteId  })
                           .Distinct()
                           .ToList();

for (int i = 1; i <= grouped.Count && finalReportDetails.Count != grouped.Count; i++)
{
    var obj = grouped[i - 1];

    // Fetch records for one group, order by rate to find the least Rate
    var grpFinalReportDetails = (from s in Rates
                                 where && s.CheckInDate == obj.CheckInDate && s.websiteId == obj.websiteId
                                 select s).OrderBy(x => x.price).ToList();

    // Deletion necessary only if there is more than one rate for same parameters
    if (grpFinalReportDetails.Count > 1)
    {
        // Tracks if a valid rate is found
        bool isFound = false;
        for (int j = 0; j < grpFinalReportDetails.Count; j++)
        {
            // Checks if a valid least rate is found
            if (!isFound && grpFinalReportDetails[j].InitialRates.Rates > 0)
            {
                isFound = true;
                continue;
            }

            // Delete all but one records whose Rate is less than 0  OR whose rate is more than the cheapest rate
            if ((grpFinalReportDetails[j].InitialRates.Rates <= 0 && j < grpFinalReportDetails.Count - 1) || isFound)
            {
                finalReportDetails.Remove(grpFinalReportDetails[j]);
            }
        }
    }
}

有没有更快的方法来使用 linq 找到相同的内容? 或者可以在这段代码中优化的东西。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    看起来这个 LINQ 查询可能会做你想做的事 - 至少,它通过了你的例子:

    var result = rates
        .GroupBy(rate => rate.websiteId)
        .Select(@group => 
            @group.Any(rate => rate.price > 0)
                ? @group.Where(rate => rate.price > 0).OrderBy(rate => rate.price).First()
                : @group.OrderBy(rate => rate.price).First())
    

    (变量名@group中的@符号是因为group是保留字。如果选择不同的变量名,则不需要@。)

    请注意,这可能会迭代您的可枚举数次,因此如果这是来自某些昂贵操作(如数据库查询)的列表,请务必先调用 .ToList(),以避免多次调用昂贵的操作.

    【讨论】:

      【解决方案2】:
      //Some initializing code for testing
      var timeValue = DateTime.Now;
      List<Rates> rates = new List<Rates>()
      {
          new Rates { CheckInDate = timeValue, websiteId = 1, price = 1 },
          new Rates { CheckInDate = timeValue, websiteId = 1, price = 2 },
          new Rates { CheckInDate = timeValue, websiteId = 2, price = -1 },
          new Rates { CheckInDate = timeValue, websiteId = 2, price = 2 },
          new Rates { CheckInDate = timeValue, websiteId = 3, price = -1 },
          new Rates { CheckInDate = timeValue, websiteId = 3, price = -1 },
      };
      
      //The actual relevant code
      var result = rates.GroupBy(item => new { item.websiteId, item.CheckInDate })
                        .Select(grp => grp.Any(item => item.price != -1) ?
                            grp.Where(item => item.price != -1).OrderBy(item => item.price).First() :
                            grp.First())
                        .ToList();
      

      【讨论】:

      • 为什么不 group.Min(item => item.price)?
      • Min by price 将返回该组的最低价格,但我想要的是具有最低priceRate
      • 有一个问题。我有一些价格 = -1 的价格。我需要选择最低价格 (>0)(第一偏好)的价格(如果存在)或价格为 -1 的价格。
      • @GiladGreen 我已经编辑了这个问题。看看例子是否清楚。
      • @GunmeetSingh - 已修复 :) 是您需要的吗?
      猜你喜欢
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 2015-05-22
      • 2012-04-08
      • 2011-11-30
      • 1970-01-01
      相关资源
      最近更新 更多