Split List into Sub lists with LINQ C#

To split the C# list into N Sub lists use the next generic helper:

public static class ListExtensions
{ public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize) { return source .Select((x, i) => new { Index = i, Value = x }) .GroupBy(x => x.Index / chunkSize) .Select(x => x.Select(v => v.Value).ToList()) .ToList(); }
}

Split Example


Here is the list of 7 persons. And I want to split it into chunks in size 2. As a result, we should have 3 chunks with 2 persons and 1 chunk with 1 person. And at the end of the program, I print results grouped by chunks.

The full code example:

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic; namespace ConsoleApp1
{ internal class Program { static void Main(string[] args) { var personList = new List<Person>(); personList.Add(new Person() { Id =10, FirstName = "Belinda", LastName = "Mcintosh" }); personList.Add(new Person() { Id = 20, FirstName = "Cory", LastName = "Mcmahon" }); personList.Add(new Person() { Id = 30, FirstName = "Joe", LastName = "Horton" }); personList.Add(new Person() { Id = 40, FirstName = "Virginia", LastName = "Rice" }); personList.Add(new Person() { Id = 50, FirstName = "Kody", LastName = "Taylor" }); personList.Add(new Person() { Id = 60, FirstName = "Gordon", LastName = "Mercer" }); personList.Add(new Person() { Id = 70, FirstName = "Carolina", LastName = "Mcintosh" }); const int chunkSize = 2; var chunks = personList.ChunkBy<Person>(chunkSize); int i=0; foreach(var c in chunks) { i++; Console.WriteLine($"Chucnk #{i}"); foreach(var person in c) { Console.WriteLine($"{person.FirstName} {person.LastName}"); } Console.WriteLine(Environment.NewLine); } } } public class Person { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } public static class ListExtensions { public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize) { return source .Select((x, i) => new { Index = i, Value = x }) .GroupBy(x => x.Index / chunkSize) .Select(x => x.Select(v => v.Value).ToList()) .ToList(); } }
}

Print Result(sorry for typo):

How Does it Work?


Let's debug each line and see what intermediate results we have on lambda expressions. To simplify our example I rewrote it in a shorter manner without a generic function:
explore lambda lines split list
Output:
view lambda expression in output window
The 'tmp1' variable contains the list of anonymous objects: {Index, Value(aka Person)}.
The 'tmp2' contains GroupedEnumerable. To understand how Group calculates I prepared a 'debug' table:














































Index Chunk Size Group(integer division Index/ChunkSize)
0 2 0
1 2 0
2 2 1
3 2 1
4 2 2
5 2 2
6 2 3


And 'tmp3' contains a list of chunked lists.

How to Split List into Sub List if you use .net 6 and C# 10


If you use C# 10 you can find a new function Chunk. Look at my article about LINQ improvement in .NET 6 where I describe how the above code could be replaced by the Chunk function.

You may also be interested in reading: