2011-08-05 4 views
44

を選択:LINQのクエリグループ化して、私はちょっと、このような文字列配列を持つ第一項目に

// icon, category, tool 
String[,] subButtonData = new String[,] 
{ 
    {"graphics/gui/brushsizeplus_icon", "Draw", "DrawBrushPlus"}, 
    {"graphics/gui/brushsizeminus_icon", "Draw", "DrawBrushMinus"}, 
    {"graphics/gui/freedraw_icon", "Draw", "DrawFree"}, 
    {"graphics/gui/linedraw_icon", "Draw", "DrawLine"}, 
    {"graphics/gui/rectangledraw_icon", "Draw", "DrawRectangle"}, 
    {"graphics/gui/ellipsedraw_icon", "Draw", "DrawEllipse"}, 
    {"graphics/gui/brushsizeplus_icon", "Brusher", "BrusherBrushPlus"}, 
    {"graphics/gui/brushsizeminus_icon", "Brusher", "BrusherBrushMinus"}, 
    {"graphics/gui/brushsizeplus_icon", "Text", "TextBrushPlus"}, 
    {"graphics/gui/brushsizeminus_icon", "Text", "TextBrushMinus"}, 
}; 

その後、私はこれは私がのためにグループ分けを照会する方法ですmainButtons

という名前の私のボタンタイプでList<Button>を移入Category

var categories = from b in mainButtons 
       group b by b.category into g 
       select new { Category = g.Key, Buttons = g }; 

メインリストの各グループの最初の項目を選択するにはどうすればよいですか? (それぞれ反復せずに別のリストに追加する必要はありません)

+2

クエリがサンプルコレクションと異なる何かを使用しているのはなぜですか? – svick

答えて

54

LINQ: How to get the latest/last record with a group by clause

var firstItemsInGroup = from b in mainButtons 
       group b by b.category into g 
select g.First(); 

を参照してください、私は仮定mainButtonsは既に正しくソートされています。

カスタムソート順を指定する必要がある場合は、CompareBでOrderBy overrideを使用します。

var firstsByCompareInGroups = from p in rows 
     group p by p.ID into grp 
     select grp.OrderBy(a => a, new CompareRows()).First(); 

私のポストの例を参照してください"Select First Row In Group using Custom Comparer「人のために

+0

ここの例とブログ記事の例は、私が必要としていたものです。ありがとう! – tjans

5

まず、多次元配列は使用しません。今まで見たことのない悪いものしか出てこない。

IEnumerable<IEnumerable<string>> data = new[] { 
    new[]{"...", "...", "..."}, 
    ... etc ... 
}; 

その後、あなたは、単に行くだろう:

var firsts = data.Select(x => x.FirstOrDefault()).Where(x => x != null); 

になりますが、内部の項目として空のリストを持っている場合は必ず、それはどんなヌルを剪定ザ・このようなあなたの変数を設定し

別法として、あなたがそれを実装することができます。これは、[x,y]配列と同様に使用することができますが、それはこのように使われています

string[][] = new[] { 
    new[]{"...","...","..."}, 
    new[]{"...","...","..."}, 
    ... etc ... 
}; 

[x][y]

+0

Arenありがとう、たくさんの男! – JML

+0

もしあなたが.Net 4にいたら、 'IEnumerable >'を使うことでもっと簡単になりますので、常に3つの項目を持つことができます。それ以前の.Net版では、独自のTupleクラスを作成する(またはインターネットから選択する、試す価値があるかもしれません)。 –

+0

.NET 4のTuplesについて私は本当に興奮していましたが、私はそれらを使用しているので、冗長性によって価値があるよりも多くの問題が生じていることがわかりました。特に複雑なタプルがあるときは、次のようになります。 'Tuple 、IDictionary 、int>'コード内のいくつかの場所を古いものにする。 – Aren

46
var result = list.GroupBy(x => x.Category).Select(x => x.First()) 
2
var results = list.GroupBy(x => x.Category) 
      .Select(g => g.OrderBy(x => x.SortByProp).FirstOrDefault()); 

は必ずしも正しくソートされないグループのためにこれを行う方法を疑問に、ここにthis answerその用途の拡大がありますメソッドの構文を使用して各グループのソート順をカスタマイズし、それぞれから目的のレコードを取得します。

LINQ-to-Entitiesを使用している場合は、FirstOrDefault()の代わりにFirst()を使用すると実行時例外が発生します。これは、前者を最終クエリ操作としてのみ使用できるためです。

関連する問題