Linq Query Group By и выбор первых элементов

У меня есть массив строк вроде этого:

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

Как я могу выбрать первый элемент каждой группы в моем основном списке? (без итерации каждого и добавления в другой список?)

4 ответа

Решение

См. LINQ: Как получить последнюю / последнюю запись с предложением group by

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

Я предполагаю, что mainButtons уже отсортированы правильно.

Если вам нужно указать пользовательский порядок сортировки, используйте переопределение OrderBy с Comparer.

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

Смотрите пример в моем посте "Выберите первую строку в группе, используя Custom Comparer"

var result = list.GroupBy(x => x.Category).Select(x => x.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); 

Где гарантирует, что он удаляет все нули, если у вас есть пустой список как элемент внутри.

В качестве альтернативы вы можете реализовать это как:

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

Это может быть использовано аналогично [x,y] массив, но он используется так: [x][y]

Другие вопросы по тегам