C# 在列表中查找最低速率<;T>;在特定的群体中

C# 在列表中查找最低速率<;T>;在特定的群体中,c#,linq,C#,Linq,我有List finalReportDetails,它包含同一WebsiteId和CheckInDate的多个费率。 我只需要为每个websiteId和checkindate创建一个记录。 此记录应具有最低比率(第一优先)或比率为-1。 Rest应从列表中删除此组的所有记录 初始列表 List<Rates> rates = new List<Rates>() { new Rates { CheckInDate = timeValue, websi

我有List finalReportDetails,它包含同一WebsiteId和CheckInDate的多个费率。 我只需要为每个websiteId和checkindate创建一个记录。 此记录应具有最低比率(第一优先)或比率为-1。 Rest应从列表中删除此组的所有记录

初始列表

 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=新列表()
{
新费率{CheckInDate=timeValue,websiteId=1,price=1},
新费率{CheckInDate=timeValue,websiteId=1,price=2},
新费率{CheckInDate=timeValue,websiteId=2,price=-1},
新费率{CheckInDate=timeValue,websiteId=2,price=2},
新费率{CheckInDate=timeValue,websiteId=3,price=-1},
新费率{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 },
        };
List rates=新列表()
{
新费率{CheckInDate=timeValue,websiteId=1,price=1},
新费率{CheckInDate=timeValue,websiteId=2,price=2},
新费率{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]);
            }
        }
    }
}
课程费率{
public int websiteId{get;set;},
公共日期时间检查日期{get;set;}
公共十进制价格{get;set;}
var grouped=(来自finalReportDetails中的s)
选择新的{s.CheckInDate,s.websiteId})
.Distinct()
.ToList();
对于(int i=1;i x.price).ToList();
//仅当同一参数有多个速率时才需要删除
如果(grpFinalReportDetails.Count>1)
{
//跟踪是否找到有效的速率
bool isFound=false;
对于(int j=0;j0)
{
isFound=true;
继续;
}
//删除速率小于0或速率大于最便宜速率的所有记录(只有一个记录除外)
if((grpFinalReportDetails[j].InitialRates.Rates
//一些用于测试的初始化代码
var timeValue=DateTime.Now;
列表费率=新列表()
{
新费率{CheckInDate=timeValue,websiteId=1,price=1},
新费率{CheckInDate=timeValue,websiteId=1,price=2},
新费率{CheckInDate=timeValue,websiteId=2,price=-1},
新费率{CheckInDate=timeValue,websiteId=2,price=2},
新费率{CheckInDate=timeValue,websiteId=3,price=-1},
新费率{CheckInDate=timeValue,websiteId=3,price=-1},
};
//实际相关代码
var result=rates.GroupBy(item=>new{item.websiteId,item.CheckInDate})
.选择(grp=>grp.Any)(项目=>item.price!=-1)?
grp.Where(item=>item.price!=-1).OrderBy(item=>item.price).First():
grp.First())
.ToList();

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

为什么不使用group.Min(item=>item.price)?
Min
by
price
将返回组的最低价格,但我想要的是
Rate
price
最低。有一个问题。我有一些price=-1的费率。我需要选择最低价格(>0)(第一个首选项)之一的费率,如果有,或者价格为-1。@GiladGreen我已经编辑了这个问题。看看这个例子是否说明得很清楚。@Gunmeetsigh-修正了:)这是你需要的吗?
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())