تقسیم لیستی از اشیا به چند لیست با استفاده از LINQ در C#
برای تقسیم یک لیست به چند لیست، بسته به نیازمان، می توانیم از روش های مختلفی در سی شارپ استفاده کنیم:
1. استفاده از GroupBy:
یکی از روشهای متداول استفاده از تابع GroupBy در LINQ است. در این روش با تقسیم کردن ایندکسها به تعداد مورد نظر میتوانید اشیا را گروهبندی کنید. به عنوان مثال:
public static List<List<T>> Split<T>(IList<T> source)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / 3)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
}
در این کد، ابتدا هر عنصر به همراه ایندکس آن تعریف میشود. سپس با استفاده از GroupBy، اشیا براساس ایندکسهای گروهبندی میشوند و در نهایت هر گروه به یک لیست تبدیل میشود.
2. استفاده از روش Chunk:
یک روش دیگر که به نوعی بیشتر از لحاظ خوانایی بهینه است، پیادهسازی تابعی به نام Chunk است. این تابع میتواند به شکل زیر پیادهسازی شود:
public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int chunksize)
{
while (source.Any())
{
yield return source.Take(chunksize);
source = source.Skip(chunksize);
}
}
در این روش، با استفاده از عملکرد Take، عناصر به تعداد مشخصی از مقدار (در اینجا ۳) گرفته میشوند و سپس با Skip باقیماندهی لیست ادامه مییابد.
در پیادهسازی این توابع، توجه به کارایی و مصرف حافظه امری حیاتی است. برای مثال، استفاده از Skip و Take میتواند در مواقعی منجر به مصرف بیش از حد حافظه شود، خصوصاً زمانی که با تعداد زیادی داده کار میکنیم. بنابراین، باید به دقت میزان استفاده از این توابع و مدیریت حافظه را بررسی کرد.
3. استفاده از قابلیت های درونی .NET در دات نت 6 به بعد
در دات نت 6.0 به بعد متد Chunk اضافه شده است که کار تقسیم را بدون دردسر و نوشتن کد اضافه برای ما انجام می دهد:
var list = Enumerable.Range(1, 100);
var chunkSize = 10;
foreach(var chunk in list.Chunk(chunkSize)) //Returns a chunk with the correct size.
{
Parallel.ForEach(chunk, (item) =>
{
//Do something Parallel here.
Console.WriteLine(item);
});
}