2010-12-03 5 views
2

해당 날짜의 최대 날짜 및 최대 값과 함께 "값"유형의 행을 반환하는 LINQ 쿼리를 작성하는 방법. 그것은 어디에 이름 = "올바른"행이어야합니다LINQ가 포함 된 하위 목록에서 최대 값 선택

나는 끝에 쿼리를 작성하고, 그것을 일하는 올바른 방법을 찾으려고 노력하고 있습니다. 사전에

감사

public class MeasurePoint 
{ 
    public int No { get; set; } 
    public string Weight { get; set; } 
    public List<Values> Vals { get; set; } 
} 

public class Values 
{ 
    public string Name { get; set; } 
    public int Val { get; set; } 
    public DateTime Date { get; set; } 
} 

public static class Test 
{ 
    public static void Calc() 
    { 
     var mps = new List<MeasurePoint>(); 

     mps.Add(new MeasurePoint() 
     { 
      No = 1, 
      Vals = new List<Values>() 
      { 
       new Values(){Date = DateTime.Now.Date.AddDays(1), Name = "testas", Val = 1}, 
       new Values(){Date = DateTime.Now.Date.AddDays(2), Name = "testas", Val = 5}, 
       new Values(){Date = DateTime.Now.Date, Name = "testas", Val = 15} 
      }}); 
     mps.Add(new MeasurePoint() 
     { 
      No = 2, 
      Vals = new List<Values>() 
      { 
       new Values(){Date = DateTime.Now.Date, Name = "testas", Val = 11}, 
       new Values(){Date = DateTime.Now.Date.AddDays(2), Name = "Correct", Val = 55}, 
       new Values(){Date = DateTime.Now.Date, Name = "testas", Val = 15} 
      } 
     }); 
     mps.Add(new MeasurePoint() 
     { 
      No = 3, 
      Vals = new List<Values>() 
      { 
       new Values(){Date = DateTime.Now.Date.AddDays(1), Name = "testas", Val = 111}, 
       new Values(){Date = DateTime.Now.Date.AddDays(2), Name = "testas", Val = 52}, 
       new Values(){Date = DateTime.Now.Date, Name = "testas", Val = 15} 
      } 
     }); 

     mps.Add(new MeasurePoint() 
     { 
      No = 4, 
      Vals = new List<Values>()      
     }); 

     var x = mps.ElementAt(0).Vals.Union(mps.ElementAt(1).Vals).Union(mps.ElementAt(2).Vals); 
     var z = x.Where(p => p.Date == x.Max(d => d.Date)).MaxBy(t=>t.Val); 

     //One more way I've found 
     var ttt = mps.SelectMany(p => p.Vals).GroupBy(t=>t.Date).MaxBy(r=>r.Key).MaxBy(g=>g.Val); 
    } 

답변

5
var max = mps.SelectMany(x => x.Vals) 
    .Aggregate((a, x) => (x.Date > a.Date) || 
         ((x.Date == a.Date) && (x.Val > a.Val)) ? x : a); 
+0

:) 멋져요 :) 어떻게 생각하세요? 작동합니다 : – Marty

+0

@Martynas :'SelectMany'는 원본 컬렉션을'Vals' 컬렉션의 모든 Values ​​개체를 포함하는 단일 시퀀스로 단순히 "평평하게"만듭니다. 모든 'MeasurePoint' 개체. 집계는 각 요소를 최대 (지금까지)와 비교하여 병합 된 시퀀스를 단계별로 실행합니다. 현재 요소가 최대 값보다 크면 그 값이 새로운 최대 값이됩니다. 모든 요소가 처리되면 최대 값이 반환됩니다. – LukeH

2

var result = mps.Where(m => m.Vals.Count > 0) 
    .SelectMany(m => m.Vals 
     .OrderByDescending(v => v.Date) 
     .Take(1), (m, v) => new {m.No, v.Date, v.Name, v.Val}); 

편집을 시도 -이 문제는 더 명백 해졌다으로 새로운 버전입니다

var result = mps.Where(m => m.Vals.Count > 0) 
    .SelectMany(m => m.Vals) 
    .OrderByDescending(v => v.Date) 
    .ThenByDescending(v => v.Val).Take(1); 
+0

Am, 최대 날짜로 레코드를 찾아야하지만 해당 날짜의 최대 "Val"을 찾아야하는 경우이 값이 정확합니다. 하지만 당신의 아이디어는 멋지 네요. 감사합니다. – Marty

+0

지금 당신의 요구 사항을 이해합니다 - 제 대답 –

+0

을 편집 해보십시오 :) 가장 좋은 수행력을주는 것을보기 위해 그들 모두를 시도 할 것입니다. – Marty

0

어떻게 MaxBy()이라면 IObservable<T>의 방법입니다. GroupBy()IEnumerable<T>을 반환합니까?

+0

Heh :) Reactive Linq Extensions를 설치했으며 완전히 잊어 버렸습니다. – Marty

+0

@Martynas : 게시물을 더 명확하게 언급 해주세요 :) – abatishchev

관련 문제