GroupBy in lambda expressions
from x in myCollection
group x by x.Id into y
select new {
Id = y.Key,
Quantity = y.Sum(x => x.Quantity)
};
How would you开发者_高级运维 write the above as a lambda expression? I'm stuck on the group into
part.
Query continuations (select...into and group...into, but not join...into) are equivalent to just splitting up the query expression. So I like to think of your example as:
var tmp = from x in myCollection
group x by x.Id;
var result = from y in tmp
select new {
Id = y.Key,
Quantity = y.Sum(x => x.Quantity)
};
Change those into dot notation:
var tmp = myCollection.GroupBy(x => x.Id);
var result = tmp.Select(y => new {
Id = y.Key,
Quantity = y.Sum(x => x.Quantity)
});
Then you could combine them back:
var tmp = myCollection.GroupBy(x => x.Id)
.Select(y => new {
Id = y.Key,
Quantity = y.Sum(x => x.Quantity)
});
Once you work out what the C# compiler does with query expressions, the rest is relatively straightforward :)
myCollection
.GroupBy(x => x.Id)
.Select(x =>
new
{
Id = x.Key,
Quantity = x.Sum(y => x.Quantity
});
myCollection.GroupBy(x => x.Id)
.Select(y => new {
Id = y.Key,
Quantity = y.Sum(x => x.Quantity)
});
var mostFrequent =
lstIn.Where(i => !string.IsNullOrEmpty(i))
.GroupBy(s => s)
.OrderByDescending(g => g.Count())
.Select(s => s.Key)
.FirstOrDefault();
So, for most of the answers here, everyone seems to be dealing with getting a simple object of Id made from count of the group, and the Key itself which is group.Key.
Although thats probably the main useage of this. Didn't really satisfy my needs.
For my own case, I basically wanted to group by some object property, then fetch a specific object from that group. Here's a sample code.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var response = new List<ResponseClass>();
var listOfStudents = new List<Student>();
// Insert some objects into listOfStudents object.
listOfStudents.GroupBy(g => g.Class).ToList()
.ForEach(g => response.Add(g.OrderByDescending(s => s.CreatedOn).Select(a =>
new ResponseClass
{
SName = a.StudentName,
SAge = a.Age,
SClass = a.Class,
SCreatedOn = a.CreatedOn,
RandomProperty = Guid.NewGuid().ToString()
})
.First()));
Console.WriteLine("This compiles and should work just fine");
}
class Student
{
public string StudentName { get; set; }
public int Age { get; set; }
public string Class { get; set; }
public DateTime CreatedOn { get; set; }
}
class ResponseClass
{
public string SName { get; set; }
public int SAge { get; set; }
public string SClass { get; set; }
public DateTime SCreatedOn { get; set; }
public string RandomProperty { get; set; }
}
}
If you would rather use a foreach loop (I prefer lambda as I find it easier to read), but if you do, you could do it like so.
foreach (IGrouping<string, Student> groupedStudents in listOfStudents.GroupBy(g => g.Class))
{
response.Add(groupedStudents.OrderByDescending(x => x.CreatedOn).Select(a =>
new ResponseClass
{
SName = a.StudentName,
SAge = a.Age,
SClass = a.Class,
SCreatedOn = a.CreatedOn,
RandomProperty = Guid.NewGuid().ToString()
}).First());
}
Hope this helps someone. :)
精彩评论