I have these two classes in my code and a List of Class2. I want to group the list elements by date
and ID
using LINQ.
public class Class1
{
public string ID;
public int y;
public int z;
}
public class Class2
{
public List<Class1> a;
public int p, q;
public string s;
public DateTime date;
}
My list is similar to this:
List<Class2> object1 = new List<Class2>
{
new Class2 {p = 5, q = 6, date = DateTime.Now, a = new List<Class1> { new Class1 { ID = "3643746HDJ", y = 0, z = 9 }, new Class1 { ID = "746327846HDJ", y = 0, z = 9 } } },
new Class2 {p = 5, q = 6, date = DateTime.Now.AddDays(1), a = new List<Class1> { new Class1 { ID = "3643746HDJ", y = 0, z = 9 }, new Class1 { ID = "746327846HDJ", y = 0, z = 9 } } },
new Class2 {p = 5, q = 6, date = DateTime.Now.AddDays(2), a = new List<Class1> { new Class1 { ID = "3643746HDJ", y = 0, z = 9 }, new Class1 { ID = "746327846HDJ", y = 0, z = 9 } } },
new Class2 {p = 5, q = 6, date = DateTime.Now.AddDays(3), a = new List<Class1> { new Class1 { ID = "3643746HDJ", y = 0, z = 9 }, new Class1 { ID = "746327846HDJ", y = 0, z = 9 } } },
};
Sorry if this is a stupid question, but I am a beginner in C# programming and LINQ and I am not sure if this is even possible.
This is what I have tried based on examples I saw on the web but its not correct
var newList = from item in object1
group new
{
item.s,
item.a[0].x, //I think its wrong because of this
item.a[0].y //and this
}
by new
{
item.date,
item.a[0].ID //and this
}
into temp
select temp;
Since I have hardcoded index 0 in the grouping I am missing a lot of elements in my final list. How can I do this for all elements of list a
in Class2
?
Expected output is similar to this:
Key: {date: 19-09-2017 ID: 3643746HDJ}, Element: {{s: "abc", y = 1, z = 2}, {s: "pqr", y = 2, z = 4}, {s: "abc", y = 1, z = 2}}
Key: {date: 20-09-2017 ID: 3643746HDJ}, Element: {{s: "pop", y = 1, z = 2}, {s: "dfr", y = 2, z = 4}, {s: "abc", y = 1, z = 2}}
Key: {date: 19-09-2017 ID: 746327846HDJ}, Element: {{s: "abc", y = 7, z = 8}, {s: "asar", y = 2, z = 111}, {s: "abc", y = 1, z = 2}}
Key: {date: 20-09-2017 ID: 746327846HDJ}, Element: {{s: "abc", y = 7, z = 8}, {s: "asar", y = 2, z = 111}, {s: "abc", y = 1, z = 2}}
You can also use Into Group with GroupBy in VB.Net. LINQ query is ended with the help Select or Groupby clause. It can also support method syntax in both C# and VB.Net languages. As shown in example 2.
LINQ GroupBy() Method In LINQ, the GroupBy operator is used to groupin the list/collection items based on the specified value of the key, and it returns a collection of IGrouping<key, Values>. The GroupBy method in LINQ is the same as the SQL group by statement.
Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query capabilities directly into the C# language. Traditionally, queries against data are expressed as simple strings without type checking at compile time or IntelliSense support.
GroupBy & ToLookup return a collection that has a key and an inner collection based on a key field value. The execution of GroupBy is deferred whereas that of ToLookup is immediate. A LINQ query syntax can be end with the GroupBy or Select clause.
Your question states:
Since I have hardcoded index 0 in the grouping I am missing a lot of elements in my final list. How can I do this for all elements of list a in Class2?
As you want all the items from the nested collections you need to flatten the nested collections before grouping. In query syntax do so using another from
:
var result = from item in object1
from nested in item.a
group new { item.s, nested.y, nested.z } by new { item.date, nested.ID } into g
select g;
As each nested object does not have a p
and q
properties but your code shows accessing the nested items I used y
and z
instead
This can also be done using method syntax. To flatten the nested collections use SelectMany
. For the GroupBy
you can use the overload where you specify both key and element selector. General idea for that:
var result = object1.SelectMany(item => item.a.Select(nested => new {item, nested }))
.GroupBy(key => new { key.item.Date, key.nested.Id },
val => new { val.item.s, val.nested.x, val.nestd.y });
Even though it seems it is only for question purposes only I recommend giving meaningful names for properties and variables and to have a look at:
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