2016-07-15 34 views
1

我有列表<费率> finalReportDetails,它包含同一WebsiteId和CheckInDate的多个费率。 我需要每个websiteId和checkindate只有一个记录。 此记录应该有最低的费率(第一优先)或费率-1。 应该从列表中删除该组的所有记录。在列表中查找最低费率<T>

初步名单

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相同? 或者这个代码中可以优化的东西。

回答

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

+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(); 
+0

为什么不能group.Min(item => item.price)? – misha130

+0

'Min' by'price'会返回组中的最低价格,但我想要的是'价格'最低的'价格'。 –

+0

有一个问题。我有一些价格= 1的价格。我需要选择最低价格(> 0)(第一优先)(如果存在)或价格(价格-1)。 –