2016-07-15 32 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)。 –