Linq查询分组依据并选择第一项

本文关键字:一项 选择 查询 Linq | 更新日期: 2023-09-27 18:04:35

我有一个字符串数组,有点像这样:

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

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

Linq查询分组依据并选择第一项

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

请参阅LINQ:如何通过子句获取带有组的最新/最后一条记录

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();

请参阅我的文章"使用自定义比较器选择组中的第一行">

中的一个示例
var results = list.GroupBy(x => x.Category)
            .Select(g => g.OrderBy(x => x.SortByProp).FirstOrDefault());

对于那些想知道如何对不一定正确排序的组执行此操作的人,下面是这个答案的扩展,它使用方法语法自定义每个组的排序顺序,从而从每个组中获得所需的记录。

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

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

这样设置变量:

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

然后你只需去:

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

Where确保在内部有空列表作为项的情况下,它会修剪任何null。

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

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

这可以类似于[x,y]阵列使用,但使用方式如下:[x][y]