متد جدید Chunk در دات نت 6
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: دو دقیقه

متد جدید ()Chunk در دات نت 6، به مجموعه‌ی LINQ اضافه شده‌است. این متد امکانی را فراهم میکند که بتوان مجموعه‌ای را به گروه‌های کوچکتر، تقسیم کنیم .


وضعیت فعلی  پیاده سازی این قابلیت 
در نسخه‌های قبلی دات نت، چنین قابلیتی برای تقسیم یک مجموعه، به مجموعه‌های کوچکتر بصورت توکار وجود ندارد.
مجموعه‌ی زیر را در نظر بگیرید:
int[] numbers = new int[] {6, 5, 1, 9, 18, 5, 3, 21};
این عملیات تقسیم به مجموعه‌های کوچکتر می‌تواند توسط متد‌های Take و Skip، انجام شود که نتیجه نهایی آنچنان چشم نواز نیست!
var coll1 = numbers.Take(2);
var coll2 = numbers.Skip(2).Take(2);
var coll3 = numbers.Skip(4).Take(2);
var coll4 = numbers.Skip(6).Take(2);

با کمی تامل شاید بتوان روش‌های بهتری نیز برای این نیاز ارائه کرد. در این پرسش و پاسخ که رای بالایی هم دارد، یک متد الحاقی برای تقسیم یک مجموعه، به زیر مجموعه‌های کوچکتر ارائه شده‌است:
static class LinqExtensions
{
    public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> list, int parts)
    {
        int i = 0;
        var splits = from item in list
                     group item by i++ % parts into part
                     select part.AsEnumerable();
        return splits;
    }
}

پیاده سازی جدید
در دات نت 6، متد جدید Chunk می‌تواند یک مجموعه را به زیر مجموعه‌های کوچکتری تبدیل کند.
فرض کنید یک مجموعه‌ی بزرگ از اعداد تصادفی را داریم:
List<int> numbers = new();

int counter = 0;
Random rand = new(DateTime.Now.Millisecond);
while(counter < 100)
{
    numbers.Add(rand.Next(1, 1000));
    counter++;
}
با استفاده از متد Chunk میتوان این مجموعه‌ی 100 عضوی را به 10 مجموعه‌ی 10 عضوی، تبدیل کرد. این متد مقداری را بعنوان پارامتر دریافت میکند که سایز زیر مجموعه‌هایی است که قرار است تولید شوند.

شرایط خاص در این متد
اگر با تقسیم مجموعه‌ی بزرگتر، زیر مجموعه‌ها تعداد یکسانی عضو نداشتند، چه اتفاقی می‌افتد؟
فرض کنید مجموعه‌ی اصلی 100 عضو و زیر مجموعه‌ها 8 عضو داشته باشند:
IEnumerable<int[]> sublists = numbers.Chunk(8);
چند زیر مجموعه تولید خواهد شد؟ هر مجموعه چند عضو را خواهد داشت؟
خروجی تابع Chunk، سیزده زیر مجموعه دارد؛  12 زیر مجموعه‌ی اول آن، 8 عضوی است که خارج قسمت صحیح تقسیم عدد 100 بر عدد 8 می‌باشد و مجموعه‌ی آخر آن، 4 عضوی است که باقیمانده‌ی تقسیم صحیح 100 بر 8 است. در زمانیکه تعداد زیر مجموعه‌ها فرد است، به این رفتار دقت داشته باشید.
  محاسبه‌ی میانگین ششمین زیر مجموعه‌ی تولید شده در قسمت فوق :
var avg=sublists.ElementAt(6).Average();
  • #
    ‫۲ سال و ۵ ماه قبل، شنبه ۱۴ اسفند ۱۴۰۰، ساعت ۱۶:۳۷
    یک مثال تکمیلی: پیاده سازی صفحه بندی با Chunk

    فرض کنید ساختار یک مقاله به این صورت تعریف شده‌است:
    public class Article
    {
        public int Id { set; get; }
    
        public string Title { set; get; }
    
        public string Content { set; get; }
    
        public int AuthorId { set; get; }
    }
    و لیست مقالات ما به صورت زیر است:
    List<Article> articles = new()
    {
        new Article { Id = 1, Title = "Best title one", Content = "Amazing content", AuthorId = 1 },
        new Article { Id = 2, Title = "Another title", Content = "More amazing content", AuthorId = 1 },
        new Article { Id = 3, Title = "Unicorns", Content = "Even more amazing content", AuthorId = 1 },
        new Article { Id = 4, Title = "Best title one", Content = "Amazing content", AuthorId = 1 },
        new Article { Id = 5, Title = "Another title", Content = "More amazing content", AuthorId = 1 },
        new Article { Id = 6, Title = "Unicorns", Content = "Even more amazing content", AuthorId = 1 },
        new Article { Id = 7, Title = "Best title one", Content = "Amazing content", AuthorId = 1 },
        new Article { Id = 8, Title = "Another title", Content = "More amazing content", AuthorId = 1 },
        new Article { Id = 9, Title = "Unicorns", Content = "Even more amazing content", AuthorId = 1 },
        new Article { Id = 10, Title = "Best title one", Content = "Amazing content", AuthorId = 1 },
        new Article { Id = 11, Title = "Another title", Content = "More amazing content", AuthorId = 1 },
        new Article { Id = 12, Title = "Unicorns", Content = "Even more amazing content", AuthorId = 1 },
    };
    اگر بخواهیم مقالات را به صورت صفحه بندی شده نمایش دهیم و هر صفحه هم فقط 5 مقاله داشته باشد، با استفاده از روش متداول استفاده‌ی از Skip و Take به قطعه کد زیر می‌رسیم:
    var pageNumber = 1;
    var itemsPerPage = 5;
    IEnumerable<Article> pageArticles = articles.Skip((pageNumber - 1) * itemsPerPage).Take(itemsPerPage);
    Console.WriteLine($"Articles of page: {pageNumber}");
    foreach (var article in pageArticles)
    {
        Console.WriteLine($" Id: {article.Id}, Title:{article.Title}, Content:{article.Content}, AuthorId:{article.AuthorId}");
    }
    که روش عملکرد آن در تصویر زیر مشخص شده‌است:

    که هر بار از تعدادی رکورد صرفنظر شده و تعدادی برداشته و نمایش داده می‌شوند. اما در حالت استفاده از متد Chunk، هر صفحه، یک عنصر از لیست آرایه‌‌های صفحات 5 تایی است:

    pageNumber = 1;
    itemsPerPage = 5;
    IEnumerable<Article[]> allPagesArticles = articles.Chunk(itemsPerPage);
    Console.WriteLine($"Articles of page: {pageNumber}");
    foreach (var article in allPagesArticles.ElementAt(pageNumber - 1))
    {
        Console.WriteLine($" Id: {article.Id}, Title:{article.Title}, Content:{article.Content}, AuthorId:{article.AuthorId}");
    }