2013-04-24 2 views
-1

나는 datetime 형식의 키와 값을 개체 목록으로 사용하여 정렬 된 사전을 검색하고 있습니다. 내가 찾고자하는 것은 사전의 각 객체에 대한 최신 값 (객체의 속성을 기반으로 함)입니다. 내 개체에는 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

답변

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을 반환하는 한 원하는만큼 각 세트의 요소를 찾을 수 있습니다.

관련 문제