GroupBy of two properties in LINQ
I know its easy to group objects by two properties, but I was wondering if it is possible to Group by one of the two properties? Probably below example will be clearer: -
Suppose I have this table: -
CategoryID Fruit
-------------------------
1 Apple
1 Grapes
2 Tablet
2 Laptop
5 Coke
6 Coke
Now I want to group this data if the CategoryIds are the same or the Fruits are the same.
Sample result: -
Group 1:-
1 Apple
1 Grapes
Group 2:-
2 Tablet
2 Laptop
Group 3:-
5 Coke
6 Coke
source to share
To add some detail to your requirements, it sounds like you want to make a regular group on CategoryID
. Then, if any of the groups contain only one item, you want them to be grouped by Fruit
. The key of this group must contain both CategoryID
and Fruit
. For groups 1 and 2 in your sample data, the property Fruit
will be the default for Fruit
. For group 3, the value CategoryID
will be the default for CategoryID
.
You can accomplish this calculation by doing two nested groups and then expanding the inner grouping again:
var groupedItems = items
.GroupBy(item => item.CategoryID)
.GroupBy(
inner => inner.Count() > 1
? new { CategoryID = inner.Key, Fruit = default(String) }
: new { CategoryID = default(Int32), inner.First().Fruit }
)
.Select(
outer => outer.Count() == 1
? new { outer.Key, Items = outer.First().ToList() }
: new { outer.Key, Items = outer.Select(inner => inner.First()).ToList() }
);
Given this input
var items = new[] {
new { CategoryID = 1, Fruit = "Apple" },
new { CategoryID = 1, Fruit = "Coke" },
new { CategoryID = 2, Fruit = "Tablet" },
new { CategoryID = 2, Fruit = "Coke" },
new { CategoryID = 5, Fruit = "Coke" },
new { CategoryID = 6, Fruit = "Coke" }
};
you get this output
Key | Items ---------------- + ----------------- CategoryId Fruit | CategoryID Fruit ---------------- + ----------------- 1 null | 1 Apple | 1 Coke ---------------- + ----------------- 2 null | 2 Tablet | 2 Coke ---------------- + ----------------- 0 Coke | 5 Coke | 6 Coke ---------------- + -----------------
source to share