Click here to Skip to main content
15,891,431 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have a list
My Requirement
I need a LINQ lambda query to Group to a list if a Condition meets else do not group.

i.e On a condition I want it to be grouped
else it should not be grouped

I have searched net - I get details on grouping on condition and I couldn't get and understand on how the remaining item should be included without grouping.

Some info found on net was for grouping Conditionally - but with that those items not meeting conditions do not include in the resultant list.

For Example

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

The expected resultant list is to be grouped by a,b but "" should not be grouped

C#
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,""} ]


Please share your solution for this.

What I have tried:

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


With the above as expected

1. Uncommenting Where clause groups only a and b==> All those items with empty value ( "" ) does not get included

2. Commenting Where clause groups a,b and "" string to make a list with 3 groups(a,b and "").
Posted
Updated 2-Sep-17 20:52pm

Something like...
C#
var resultantList = sigList
    .Where(x => !string.IsNullOrEmpty(x.SignalGroup))
    .GroupBy(s => s.SignalGroup)
    .Select(grp => grp.ToList());
 
Share this answer
 
Comments
BillWoodruff 1-Sep-17 14:05pm    
+5
More like:

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


Let me break it down:
You want to have each empty string in it's own group (not excluded like the first solution). The easiest way to do that is to group by something unique, such as the index. You can map the index using the Select extension:
C#
.Select((x,i) => new {Item=x,Index=i})

This will return an anonymous class with Item and Index as Parameters
We still want the other items to group by their own SignalGroup. I hope that these won't be ints so you won't get any random mis-groupings. We can group by the SignalGroup if there is one, or the unique index if there isn't:
C#
.GroupBy(a =>  string.IsNullOrEmpty(a.Item.SignalGroup)?a.Index.ToString():a.Item.SignalGroup)


Now we just need to select out the original item from the anonymous class. We can do this using the select extension for each item within the group:
C#
.Select(grp => grp.Select(a=>a.Item).ToList());


That should be spot on what you asked for ^_^


UPDATE
Ooh - I forgot that you can specify the items to be grouped in the groupby:
C#
.GroupBy(a =>  string.IsNullOrEmpty(a.Item.SignalGroup)?a.Index.ToString():a.Item.SignalGroup, a=>a.Item)


Then you don't need to select out the items in the last step:
C#
.Select(grp => grp.ToList());


Either way is fine
 
Share this answer
 
v2
I got the below and it works as expected
C#
var resultantList = sigList  
.GroupBy(s => s.SignalGroup == "" ? s.SignalID.ToString() : s.SignalGroup)  
.Select(grp => grp.ToList())  
.ToList();  
 
Share this answer
 
Comments
Andy Lanng 5-Sep-17 3:43am    
Oic. The signal id in unique! Nice 👍

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900