查找特定组中的列表中的最小速率

本文关键字:速率 列表 查找 | 更新日期: 2023-09-27 17:57:02

我有List finalReportDetails,它包含同一WebsiteId和CheckInDate的多个费率。我只需要为每个网站 ID 和签入日期提供一条记录。此记录应具有最低速率(第一首选项)或速率为 -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 找到相同的内容?或者可以在此代码中优化的内容。

查找特定组中的列表<T>中的最小速率

似乎这个 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(),以避免多次调用昂贵的操作。

//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();