LINQ - GroupBy a key and then put each grouped item into separate 'buckets'

南楼画角 提交于 2019-12-04 00:03:48

You can use GroupBy:

var groups = items.GroupBy(item => item.ListId);

foreach(var group in groups)
{
     Console.WriteLine("List with ID == {0}", group.Key);
     foreach(var item in group)
        Console.WriteLine("    Item: {0}", item.ItemName);
}

Let's create your list of items:

List<Item> items = new List<Item>();
items.Add(new Item() { ItemId = 1, ItemName = "Test1", ListId = 1 });
items.Add(new Item() { ItemId = 2, ItemName = "Test2", ListId = 1 });
items.Add(new Item() { ItemId = 3, ItemName = "Test3", ListId = 1 });
items.Add(new Item() { ItemId = 4, ItemName = "List", ListId = 2 });
items.Add(new Item() { ItemId = 5, ItemName = "List2", ListId = 2 });
items.Add(new Item() { ItemId = 6, ItemName = "Testing", ListId = 3 });
items.Add(new Item() { ItemId = 7, ItemName = "Testing2", ListId = 3 });
items.Add(new Item() { ItemId = 8, ItemName = "Testing3", ListId = 3 });

var groupByResult = items.GroupBy(i => i.ListId);

After this GroupBy call, groupByResult is a variable of type IEnumerable<IGrouping<int, Item>> which is basically a collection of objects that implement IGrouping interface. This allows you to iterate through all items as IGrouping is derived from IEnumerable<> and has an extra field named Key:

public interface IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable
{
    TKey Key { get; }
}

Briefly said, a GroupBy method call returns a list of lists. An outer list corresponds to 'buckets' as you mentioned in your question. Then each 'bucket' contains items corresponding to that 'bucket'. To be specific to your example, the value of groupByResult is depicted in this screenshot. As we can see there, your initial collection was grouped into three different buckets that have 3, 2 and 3 items, respectively.

As for accessing items in these groups, you can use simple LINQ:

List<Item> firstBucketItems = groupByResult.First(i => i.Key == 1).ToList();
List<Item> secondBucketItems = groupByResult.First(i => i.Key == 2).ToList();
List<Item> thirdBucketItems = groupByResult.First(i => i.Key == 3).ToList();

Or you can just iterate through all items:

foreach (var itemGroup in groupByResult)
{
    int groupKey = itemGroup.Key;

    foreach (Item item in itemGroup)
    {
        // Do whatever...
    }
}
    IList<Student> studentList = new List<Student>()
    { 
    new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
    new Student() { StudentID = 2, StudentName = "Steve",  Age = 21 } ,
    new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
    new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
    new Student() { StudentID = 5, StudentName = "Abram" , Age = 21 } 
    };

var groupedResult = from s in studentList group s by s.Age;

//iterate each group

foreach (var ageGroup in groupedResult)
{
    Console.WriteLine("Age Group: {0}", ageGroup.Key); //Each group has a key 

    foreach(Student s in ageGroup) // Each group has inner collection
        Console.WriteLine("Student Name: {0}", s.StudentName);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!