jeAntoni Ответов: 3

В C# LINQ для группы список, если условие соответствует еще не группа


У меня есть список
мое требование
Мне нужен лямбда-запрос LINQ для группировки в список, если условие удовлетворяет else do not group.

то есть при условии, что я хочу, чтобы он был сгруппирован
иначе он не должен быть сгруппирован

Я искал в сети-я получаю подробную информацию о группировке по условию, и я не мог получить и понять, как оставшийся элемент должен быть включен без группировки.

Некоторая информация, найденная в сети, предназначалась для условной группировки-но при этом те элементы, которые не удовлетворяют условиям, не включаются в результирующий список.

например

List<signal> = [{1,"a"},{40,""),{9,"a"},{52,"b"),{2,"b"},{99,""),{88,"b"}]

Ожидаемый результирующий список должен быть сгруппирован по a,b, но "" не должен быть сгруппирован

ResultantList = Group[0] ==> [{1,"a"}
                             {9,"a"}],
                 Group[1] ==>[ {52,"b"),
                               {2,"b"},
                               {88,"b"}] ,
                 // all other items which is "" should be included without groups
                Group[3] [ {40,""}]  
                 Group[4][ {99,""} ]


Пожалуйста, поделитесь своим решением для этого.

Что я уже пробовал:

var resultantList =  sigList
                    .GroupBy(s => s.SignalGroup)
                    .Select(grp => grp.ToList())
                     //.Where(g => !g.Any(grp => grp.SignalGroup == ""))
                     .ToList();


С вышеизложенным как и ожидалось

1. Раскомментирование, где предложение группирует только a и b==> Все те элементы с пустым значением ( "" ) не включаются

2. Комментируя предложение where, группы A,B и строки"", чтобы сделать список с 3 группы(А,В и "").

3 Ответов

Рейтинг:
2

Graeme_Grant

Что-то вроде...

var resultantList = sigList
    .Where(x => !string.IsNullOrEmpty(x.SignalGroup))
    .GroupBy(s => s.SignalGroup)
    .Select(grp => grp.ToList());


BillWoodruff

+5

Рейтинг:
2

jeAntoni

Я получил ниже, и это работает, как и ожидалось

var resultantList = sigList  
.GroupBy(s => s.SignalGroup == "" ? s.SignalID.ToString() : s.SignalGroup)  
.Select(grp => grp.ToList())  
.ToList();  


Andy Lanng

Начальник. Идентификатор сигнала в unique! Милый 👍

Рейтинг:
0

Andy Lanng

Скорее:

var resultantList = sigList
    .Select((x,i) => new {Item=x,Index=i})
    .GroupBy(a =>  string.IsNullOrEmpty(a.Item.SignalGroup)?a.Index.ToString():a.Item.SignalGroup)
    .Select(grp => grp.Select(a=>a.Item).ToList());


Позвольте мне разбить его:
Вы хотите иметь каждую пустую строку в своей собственной группе (не исключено, как в первом решении). Самый простой способ сделать это-сгруппировать по чему-то уникальному, например по индексу. Вы можете сопоставить индекс с помощью расширения Select:
.Select((x,i) => new {Item=x,Index=i})

Это вернет анонимный класс с элемента и индекса в качестве параметров
Мы все еще хотим, чтобы другие элементы группировались по их собственной сигнальной группе. Я надеюсь, что это не будут Инты, так что вы не получите никаких случайных неправильных группировок. Мы можем сгруппироваться по сигнальной группе, если она есть, или по уникальному индексу, если ее нет:
.GroupBy(a =>  string.IsNullOrEmpty(a.Item.SignalGroup)?a.Index.ToString():a.Item.SignalGroup)


Теперь нам просто нужно выбрать исходный элемент из анонимного класса. Мы можем сделать это с помощью расширения select для каждого элемента в группе:
.Select(grp => grp.Select(a=>a.Item).ToList());


Это должно быть точь-в-точь то, что вы просили ^_^


ОБНОВЛЕНИЕ
Ох-я забыл, что вы можете указать элементы, которые будут сгруппированы в groupby:
.GroupBy(a =>  string.IsNullOrEmpty(a.Item.SignalGroup)?a.Index.ToString():a.Item.SignalGroup, a=>a.Item)


Тогда вам не нужно выбирать элементы на последнем шаге:
.Select(grp => grp.ToList());


В любом случае это нормально