2013-04-24 46 views
-1

我正在搜索排序的字典與鍵入日期時間和值的鍵作爲對象列表。我需要找到的是字典中每個對象的最新值(基於對象的屬性)。我的對象有3個屬性:創建時的名稱,值和日期。我的字典按最新日期降序排列。Linq查詢搜索字典中的列表作爲值列表中的對象

我已經得到了這個工作,但我敢肯定有這個使用LINQ的快捷方式。請注意,我正在使用.NET 3.5。能否請你幫忙?請不要被下面的鉅額代碼拖延,因爲我已經添加了它清晰,我只是尋找一個linq查詢列表對象列表中查詢。下面

代碼:

public void Should_link_recent_data_together() 
{ 
    var data = TimeSeriesDataFactoryEx.GetData(); 

    var allAttributes = new List<string>() 
    { 
     TimeSeriesConstants.TOTAL_COST_CODE, 
     TimeSeriesConstants.TOTAL_VALUE_CODE, 
     TimeSeriesConstants.SOURCE_CODE 
    }; 

    var latestList = new List<TimeSeries>(); 

    var allValues = data.Values.ToList(); 


    #region HOW DO I DO THIS USING LINQ? 

    bool found = false; 

    foreach (var attribute in allAttributes) 
    { 
     found = false; 
     foreach (var tsData in allValues) 
     { 
      foreach (var ts in tsData) 
      { 
       if (ts.MetricName == attribute && !string.IsNullOrEmpty(ts.MetricValue)) 
       { 
        latestList.Add(ts); 
        found = true; 
        break; 
       } 
      } 
      if (found) 
       break; 
     } 
    } 

    #endregion 

    Assert.IsTrue(latestList.Count == 3); 
    Assert.IsTrue(latestList.Where(x => x.MetricName == TimeSeriesConstants.TOTAL_COST_CODE).First().MetricValue == "1"); 
    Assert.IsTrue(latestList.Where(x => x.MetricName == TimeSeriesConstants.TOTAL_VALUE_CODE).First().MetricValue == "2"); 
    Assert.IsTrue(latestList.Where(x => x.MetricName == TimeSeriesConstants.SOURCE_CODE).First().MetricValue == "gp"); 
    Assert.IsTrue(latestList.Where(x => x.MetricName == TimeSeriesConstants.SOURCE_CODE).First().Quarter == DateTime.Today.AddMonths(-3)); 

} 



internal class TimeSeriesDataFactoryEx 
{ 
    public static SortedDictionary<DateTime?,List<TimeSeries>> GetData() 
    { 
     return new SortedDictionary<DateTime?, List<TimeSeries>>(new DateComparer()) 
     { 
      { 
       DateTime.Today, new List<TimeSeries>() 
       { 
        new TimeSeries() 
        { 
         Quarter = DateTime.Today, 
         MetricValue = "1", 
         MetricName = TimeSeriesConstants.TOTAL_COST_CODE 
        }, 
        new TimeSeries() 
        { 
         Quarter = DateTime.Today, 
         MetricValue = "2", 
         MetricName = TimeSeriesConstants.TOTAL_VALUE_CODE 
        }, 
        new TimeSeries() 
        { 
         Quarter = DateTime.Today, 
         MetricValue = "", 
         MetricName = TimeSeriesConstants.SOURCE_CODE 
        } 
       } 
      }, 
      { 
       DateTime.Today.AddMonths(-3), new List<TimeSeries>() 
       { 
        new TimeSeries() 
        { 
         Quarter = DateTime.Today.AddMonths(-3), 
         MetricValue = "3", 
         MetricName = TimeSeriesConstants.TOTAL_COST_CODE 
        }, 
        new TimeSeries() 
        { 
         Quarter = DateTime.Today.AddMonths(-3), 
         MetricValue = "4", 
         MetricName = TimeSeriesConstants.TOTAL_VALUE_CODE 
        }, 
        new TimeSeries() 
        { 
         Quarter = DateTime.Today.AddMonths(-3), 
         MetricValue = "gp", 
         MetricName =TimeSeriesConstants.SOURCE_CODE 
        } 
       } 
       } 

     }; 
    } 
} 
+0

我認爲你應該縮進你的代碼多一點,我們仍然可以看到你的一些代碼沒有滾動權。 – I4V 2013-04-24 19:26:44

回答

0

因此,假設我明白你的問題吧,說你有一個字典,像這樣:

{ Key = "1/1/1900", Value = List Of Objects, of which each has a DateTimeProperty } 
... 
{ Key = "1/4/1900", Value = List Of Objects, of which each has a DateTimeProperty } 

你正在尋找找到一組對象的你字典,它是每個鍵的最新時間,那麼你可以用linq簡單地做到這一點:

var latestItems = data.SelectMany(kvp => 
    kvp.Value.OrderByDescending(value => value.Quarter).Take(1) 
); 

該查詢查找每個存儲桶中最近的對象,然後將其作爲單個集合返回(而不是可枚舉的枚舉)。您可以更改SelectMany中的選擇器,只要您從該回調中返回IEnumerable,就可以隨意查找每個集合中的元素。