I am having a hard time creating working Group By and Sort By clauses against a generic List myList. myList has a list of property 'Settings' which itself contains a list of 'child' properties for each business.
I want to group by a Industry and within each Industry, sort by business name. My intent would be this:
string groupSetting = "Industry";
sortSetting = "BusinessName";
myList.GroupBy(p => p.Settings.Find(s => s.Name == groupSetting)).OrderBy(p => p.Settings.Find(t => t.Name == sortSetting));
However I am getting the error : 'System.Linq.IGrouping does not contain a definition for Settings and no extension method Settings accepting a first argument of type System.Linq.Igrouping could be found....' indicating I cannot invoke the order by clause without some transformation or additional treatment.
I have tried all sorts of things to split this out and get it working, but I am missing something. Any help appreciated
Your problem is that GroupBy
doesn't return a single list of settings, it returns a "list-of-lists". This is the IGrouping
which you are seeing.
You need to iterate over each group in the IGrouping
, sort that group, and then iterate over each item within the group. Observe:
public static void Main( string[] args )
{
var groupSetting = "Industry";
// step 1: group the data. Note this doesn't actually create copies of the data as
// it's all lazy loaded
// BEWARE. If a company doesn't have the "Industry" setting, this will throw an exception
var grouped = companies.GroupBy(c => c.Settings.First(s => s.Name == groupSetting).Value);
foreach( var group in grouped )
{
Console.WriteLine(group.Key);// this is the Value that came out of the GroupBy
// Note how we have to do the ordering within each individual group.
// It doesn't make sense to try group them in one hit like in your question
foreach( var item in group.OrderBy(bus => bus.Name) )
Console.WriteLine(" - " + item.Name);
}
}
Data structures provided for clarity:
struct Setting { public string Name; public string Value; }
struct Business { public string Name; public IEnumerable<Setting> Settings; }
static IEnumerable<Business> companies = new[]{
new Business{ Name = "XYZ Inc.", Settings = new[]{
new Setting{ Name="Age", Value="27"},
new Setting{ Name="Industry", Value="IT"}
}},
new Business{ Name = "Programmers++", Settings = new[]{
new Setting{ Name="Age", Value="27"},
new Setting{ Name="Industry", Value="IT"}
}},
new Business{ Name = "Jeff's Luxury Salmon", Settings = new[]{
new Setting{ Name="Age", Value="63"},
new Setting{ Name="Industry", Value="Sports"}
}},
new Business{ Name = "Bank of Khazakstan", Settings = new[]{
new Setting{ Name="Age", Value="30"},
new Setting{ Name="Industry", Value="Finance"}
}},
};
This produces the following output: Copy/paste the code and run it and play with it
IT
- Programmers++
- XYZ Inc.
Sports
- Jeff's Luxury Salmon
Finance
- Bank of Khazakstan
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With