Linq查询分组依据并select第一项

我有一个string数组有点像这样:

// 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"}, }; 

然后我用名为mainButtonsbuttontypes填充List<Button>

这是我如何查询分类的Category

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

我怎样才能select我的主要列表中的每个组的第一个项目? (没有迭代每个添加到另一个列表?)

请参阅LINQ:如何使用group by子句获取最新/最后一条logging

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

我假设mainButtons已经正确sorting。

如果您需要指定自定义sorting顺序,请使用Comparer对OrderBy进行覆盖。

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

在我的文章“使用自定义比较器在组中select第一行 ”

 var result = list.GroupBy(x => x.Category).Select(x => x.First()) 

首先,我不会使用multidimensional array。 只见过不好的事情。

像这样设置你的variables:

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

那么你只需要去:

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

如果你有一个空的列表作为一个项目里面确定它删除任何空值。

或者,您可以将其实现为:

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

这可以类似于[x,y]数组使用,但它的使用方式如下: [x][y]

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

对于那些想知道如何为不需要正确sorting的组做准备的人,这里有一个扩展的答案 ,它使用方法语法来定制每个组的sorting顺序,从而得到每个组的sorting顺序。

注意:如果您使用的是LINQ-to-Entities,那么如果您在此使用First()而不是FirstOrDefault(),则会得到运行时exception,因为前者只能用作最终查询操作。