Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need help in a grouping using LINQ in C#

Tags:

c#

linq

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}}
like image 504
Anon Avatar asked Sep 18 '17 19:09

Anon


People also ask

How can we do a GroupBy using LINQ query?

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.

What is GroupBy in C# LINQ?

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.

What is the need of LINQ in C#?

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.

What does GroupBy return in LINQ?

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.


1 Answers

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:

  • MSDN Naming Conventions
  • Dofactory
like image 90
Gilad Green Avatar answered Sep 30 '22 05:09

Gilad Green