2016-08-11 1 views
4

私は、タイプ、日付、および値を含む一連のデータを持っています。どのようにしてグループ内の要素をlinqクエリで並べ替え、最初の?

タイプごとにグループ化したいと思います。各グループの値のセットごとに、最新の日付のグループを選択したいと思います。

ここでは、動作し、正しい結果を与えるいくつかのコードですが、私は繰り返しではなく、1つのlinqクエリですべて行いたいと思います。純粋にlinqクエリでこれと同じ結果をどのように達成することができますか?

using System; 
using System.Linq; 
using System.Collections.Generic; 

public class Program { 

    public static void Main() { 

     var mydata = new List<Item> { 
      new Item { Type = "A", Date = DateTime.Parse("2016/08/11"), Value = 1 }, 
      new Item { Type = "A", Date = DateTime.Parse("2016/08/12"), Value = 2 }, 
      new Item { Type = "B", Date = DateTime.Parse("2016/08/20"), Value = 3 }, 
      new Item { Type = "A", Date = DateTime.Parse("2016/08/09"), Value = 4 }, 
      new Item { Type = "A", Date = DateTime.Parse("2016/08/08"), Value = 5 }, 
      new Item { Type = "C", Date = DateTime.Parse("2016/08/17"), Value = 6 }, 
      new Item { Type = "B", Date = DateTime.Parse("2016/08/30"), Value = 7 }, 
      new Item { Type = "B", Date = DateTime.Parse("2016/08/18"), Value = 8 }, 
     }; 

     var data = mydata.GroupBy(_ => _.Type); 

     foreach (var thing in data) { 

      #region 

      // How can I remove this section and make it part of the group by query above... ?   
      var subset = thing.OrderByDescending(_ => _.Date); 
      var top = subset.First(); 

      #endregion 

      Console.WriteLine($"{thing.Key} {top.Date.ToString("yyyy-MM-dd")} {top.Value}"); 

     }   
    } 

    public class Item { 

     public string Type {get;set;} 
     public DateTime Date {get;set;} 
     public int Value {get;set;} 

    } 
} 

// Output: 
// A 2016-08-12 2 
// B 2016-08-30 7 
// C 2016-08-17 6 
+2

。 – sstan

答えて

7

使用selectが取得するFirstOrDefault(またはFirst - あなたがnullを取得することはありませんグループ化のため)降順順序:

var data = mydata.GroupBy(item => item.Type) 
       .Select(group => group.OrderByDescending(x => x.Date) 
       .FirstOrDefault()) 
       .ToList(); 

またはSelectManyを一緒にTake(1)

var data = mydata.GroupBy(item => item.Type) 
       .SelectMany(group => group.OrderByDescending(x => x.Date) 
       .Take(1)) 
       .ToList(); 
+0

セミコロンがありません –

+0

@エサン - 今すぐ修正 –

+0

すべての回答は良いですし、1つを選択するのは難しいですが、SelectManyで代替案を出しました。ありがとう! – BG100

2

Selectの順序付きグループの最初の要素:

var topItems = mydata.GroupBy(item => item.Type) 
        .Select(group => group.OrderByDescending(item => item.Date).First()) 
        .ToList(); 

topItemsTypeあたりわずかトップ項目を含むList<Item>です。


ます。またDictionary<string,Item>がそのTypeのためのトップItemType文字列をマッピングするとして、それを取り出すことがあります。

var topItems = mydata.GroupBy(item => item.Type) 
        .ToDictionary(group => group.Key, 
           group => group.OrderByDescending(item => item.Date).First()); 
1

グループのタイプによって、グループごとに、日付の降順でそれを注文すると、最初に選びます(最新)。あなたが実際に使用しないパラメータのパラメータ名は非常に珍しいとアンダースコアを使用して

mydata.GroupBy(i => i.Type).Select(g => g.OrderByDescending(i => i.Date).First()); 
+0

まったく同じコードの回答がたくさんあります。もう1つはなぜですか?何が違うのですか? – sstan

+0

@sstanこれらの答えを私と違うものにするには?私はちょうど質問を見て、正しく答えた –

+0

それはあなたに私の質問です:)あなたがそれに答えることを望んでいた方法で他の人が既に回答しているのは明らかです。 – sstan

2
var data = mydata.GroupBy(
    item => item.Type, 
    (type, items) => items.OrderByDescending(item => item.Date).First()); 

foreach (var item in data) 
{ 
    Console.WriteLine($"{item.Type} {item.Date.ToString("yyyy-MM-dd")} {item.Value}"); 
} 
関連する問題