我有List< Rates> 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有没有更快的方法来找到它? 或者可以在此代码中优化的内容。
答案 0 :(得分:1)
//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();
答案 1 :(得分: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
是保留字。如果您选择其他变量名称,则不需要{{1 }}。)
请注意,这可能会多次遍历您的可枚举,因此如果这是来自某些昂贵操作的列表(如数据库查询),请务必先调用@
,以避免更多地调用昂贵的操作不止一次。