2010-12-03 2 views
2

Как написать запрос LINQ, который бы возвращал строку типа «Значение» с Max Date и Max для этой даты. это должна быть строка, где name = «Исправить»Выберите максимальное значение из подписок с 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

:) Cool :) Теперь идея, как это работает, но она делает :) – Marty 2010-12-03 11:05:17

+0

@Martynas: `SelectMany` просто« выравнивает »вашу исходную коллекцию в одну последовательность, содержащую все объекты« Значения »из коллекций« Vals » все объекты «MeasurePoint». Затем «Агрегат» проходит через сплющенную последовательность, сравнивая каждый элемент с максимальным (до сих пор). Если текущий элемент больше max, то это становится новым max. Когда все элементы обработаны, возвращается max. – LukeH 2010-12-03 11:27:00

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}); 

EDIT - это новая версия, как проблема стала более ясной

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, это было бы правильно, если бы мне нужно было найти запись по дате Max, но также нужно найти максимальный «Val» для этой даты. Но твоя идея приятная :) спасибо – Marty 2010-12-03 11:37:02

0

Как может использовать звонок MaxBy(), если это метод IObservable<T> между тем GroupBy() возвращает IEnumerable<T>?

Смежные вопросы