Linq查询分组和选择第一项

JML*_*JML 57 .net c# 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"},
};
Run Code Online (Sandbox Code Playgroud)

然后我List<Button>使用名为的Button Type 填充amainButtons

这是我查询分组的方式Category:

var categories = from b in mainButtons
                 group b by b.category into g
                 select new { Category = g.Key, Buttons = g };
Run Code Online (Sandbox Code Playgroud)

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

Osc*_*das 68

var result = list.GroupBy(x => x.Category).Select(x => x.First())
Run Code Online (Sandbox Code Playgroud)

  • 如果您在第一次查询之后尝试执行任何其他操作(例如选择列的子集),则从 EF 6.0 开始,这将不起作用 - 您需要使用 `x.FirstOrDefault`,否则您将获得 'First can only be用作最终操作异常' (4认同)

MiF*_*vil 62

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

var firstItemsInGroup = from b in mainButtons
                 group b by b.category into g
select g.First();
Run Code Online (Sandbox Code Playgroud)

我假设mainButtons已经正确排序.

如果需要指定自定义排序顺序,请对Comparer使用OrderBy override.

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

看到我后一个例子"使用自定义比较选择第一行集团 "


iha*_*ake 14

var results = list.GroupBy(x => x.Category)
            .Select(g => g.OrderBy(x => x.SortByProp).FirstOrDefault());
Run Code Online (Sandbox Code Playgroud)

对于那些想知道如何为那些群体做到这一点并不一定正确排序,这里的扩展这个答案,使用方法的语法自定义每个组的排序顺序,从而获取每个所需的记录.

注意:如果您正在使用LINQ-to-Entities,那么如果您在此处使用First()而不是FirstOrDefault(),则会出现运行时异常,因为前者只能用作最终查询操作.


Are*_*ren 5

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

像这样设置你的变量:

IEnumerable<IEnumerable<string>> data = new[] {
    new[]{"...", "...", "..."},
    ... etc ...
};
Run Code Online (Sandbox Code Playgroud)

然后你就去:

var firsts = data.Select(x => x.FirstOrDefault()).Where(x => x != null); 
Run Code Online (Sandbox Code Playgroud)

如果你有一个空列表作为一个项目,Where确保它修剪任何空值.

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

string[][] = new[] {
    new[]{"...","...","..."},
    new[]{"...","...","..."},
    ... etc ...
};
Run Code Online (Sandbox Code Playgroud)

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

  • 只要你必须拼出你的类型,你就是对的.在许多(大多数?)案例中,`Tuple.Create`做得很好,因为c#为你推断了类型.尽管如此,我还是谨慎地使用元组,因为它们非常非不明白(什么是Item1 ???).在公共API中,它们应该被法律禁止. (5认同)