Linq查询分组和选择第一项

时间:2011-08-05 23:41:10

标签: c# .net 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"},
};

然后我使用名为List<Button>

的按钮类型填充mainButtons

这就是我查询Category的分组的方法:

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

如何在主列表中选择每个组的第一项? (没有迭代每个并添加到另一个List?)

4 个答案:

答案 0 :(得分:60)

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

答案 1 :(得分:59)

请参阅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已经正确排序。

如果您需要指定自定义排序顺序,请使用带有Comparer的OrderBy覆盖。

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中的示例“

答案 2 :(得分:9)

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

对于那些想知道如何为正确排序的组执行此操作的人,这里是this answer的扩展,它使用方法语法来自定义每个的排序顺序小组,因此从每个小组得到所需的记录。

注意:如果你正在使用LINQ-to-Entities,如果你在这里使用First()而不是FirstOrDefault(),你会得到一个运行时异常,因为前者只能用作最终查询操作。

答案 3 :(得分:5)

首先,我不会使用多维数组。只见过不好的事情。

设置你的变量:

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]