آموزش کاربرد و روش استفاده از DistinctBy در Linq

DistinctBy

در این مقاله در مورد گرفتن اشیای غیر تکراری با استفاده از Property اش از قسمت Collection صحبت خواهیم کرد. در اینجا به شما سه روش متفاوت برای دستیابی آسان به آن را نشان خواهم داد. در این پست میخواهم در رابطه با متد های extension که قادر به انجام وظایف بیشتری نسبت به متد های Distinct موجود در چارچوب .NET هستند ، صحبت کنم.یک نمونه سورس نیز در انتها برایتان قرار داده ام. پس با من همراه باشید …

متد های DistinctBy در Linq هم اکنون مانند زیر کار میکنند.

public class Product
{
    public string Name { get; set; }
    public int Code { get; set; }
}

در نظر بگیرید ما کلاس Product داریم که دارای خصوصیات Name و Code میباشد. حال احتیاجات ما یافتن همه ی محصولات با استفاده از مقادیر distinct Code است.

Product[] products = { new Product { Name = "apple", Code = 9 }, 
                       new Product { Name = "orange", Code = 4 }, 
                       new Product { Name = "apple", Code = 10 }, 
                       new Product { Name = "lemon", Code = 9 } };
var lstDistProduct = products.Distinct();
foreach (Product p in list1)
{
     Console.WriteLine(p.Code + " : " + p.Name);
}

 خروجی

DistinctBy در Linq

تمامی رویداد های محصولات را حتی در صورت وجود دو محصول با مقدار کد یکسان ، برمیگرداند. پس این با احتیاجات دریافت اشیا با مقادیر Distinct Code همخوانی ندارد.

روش اول : استفاده از کتابخانه ی MoreLinq

اولین روش برای دستیابی به احتیاجات ، استفاده از کتابخانه ی MoreLinq است که از تابعی بنام DistinctBy پشتیبانی میکند به طوری که میتوانید خصوصیاتی که مایل به یافتن اشیای Distinct آن هستید را مشخص کنید.

کد زیر استفاده ی این تابع را نشان میدهد.

var list1 = products.DistinctBy(x=> x.Code);




foreach (Product p in list1)
{
     Console.WriteLine(p.Code + " : " + p.Name);
}

 خروجی

DistinctBy در Linq

همانطور که میتوانید در خروجی ببینید تنها دو شئ برگردانده میشوند که در واقع من مقدار i.e. distinct را توسط کد یا محصول میخواهم.

اگر قصد پاس دادن بیش از یک Property که به طور معمول قادر به انجام آن هستید ، داشته باشید میتوانید همانند زیر عمل کنید :

var list1 = products.DistinctBy(a => new { a.Name, a.Code ));

و یک نکته ی دیگر در رابطه با این کتابخانه این است که شامل اعدادی از توابع دیگر است که میتوانید چک کنید.

روش دوم : اجرای قابل قیاس

روش دوم دستیابی به تابعیت مشابه ، استفاده از تابع Distinct برای پشتیبانی ، داشتن Comparator به عنوان آرگومان است.

پس به این منظور من IEqualityComparer را اجرا میکنم و یک ProductComparare ایجاد میکنم که در زیرمیتوانید کد مربوط به آن را تماشا کنید.

   class ProductComparare : IEqualityComparer<product>
    {
        private Func<Product, object> _funcDistinct;
        public ProductComparare(Func<Product, object> funcDistinct)
        {
            this._funcDistinct = funcDistinct;
        }




        public bool Equals(Product x, Product y)
        {
            return _funcDistinct(x).Equals(_funcDistinct(y));
        }




        public int GetHashCode(Product obj)
        {
            return this._funcDistinct(obj).GetHashCode();
        }
    }
</product>

پس در ساختار ProductComparare من تابع را به عنوان یک آرگومان پاس میدهم ، پس زمانی که یک شئ از آن میسازیم من باید تابع پروژه ام را به عنوان یک آرگومان پاس بدهم.

در متد Equal اشیایی که توسط تابع my projection برگردانده میشود را مقایسه میکنیم.

حال در زیر روشی که من از این اجرای مقایسه برای رفع احتیاجات استفاده کرده ام ، آورده شده است :

var list2 = products.Distinct(new ProductComparare( a => a.Code ));




            foreach (Product p in list2)
            {
                Console.WriteLine(p.Code + " : " + p.Name);
            }

 خروجی

DistinctBy در Linq

پس با استفاده از این روش احتیاجات مان نیز یه راحتی برآورده میشود. من به داخل کد کتابخانه ی MoreLinq نگاه نکرده ام اما به نظرم آن هم همین کار را انجام میدهد. اگر مایل به ارسال بیش از یک خصوصیت بودید میتوانید مانند زیر عمل کنید :

var list1 = products.Distinct(a => new { a.Name, a.Code });

 روش سوم : استفاده از GroupBy

سومین و آسان ترین روش که برای جلوگیری از کاری که در قسمت بالا انجام دادم مانند استفاده از MoreLine و اجرا کننده ی مقایسه گر فقط از GroupBy مانند زیر استفاده میکنیم :

List<Product> list = products
                   .GroupBy(a => a.Code )
                   .Select(g => g.First())
                   .ToList();




            foreach (Product p in list)
            {
                Console.WriteLine(p.Code + " : " + p.Name);
            }

در کد قسمت بالا من گروه بندی اشیا بر اساس Property های آنها را انجام داده ام و سپس در تابع Select تنها با انتخاب یکی از گروه ها ، کار انجام میشود.

خروجی

DistinctBy در Linq

پس این روش نیز نیازمان را به راحتی برآورده میکند و خروجی آن نیز مشابه دو روش بالا است. اگر قصد ارسال بیش از یک Property را داشتید میتوانید هماننذ زیر عمل کنید :

GroupBy(a => new { a.Name, a.Code })

پس این یک ترفند بسیار آسان برای دستیابی به تابعیتی است که میخواستیم ؛ بدون استفاده از چیزی اضافه در کد مان.

جمع بندی

پس در بالا روش هایی که میتوانید به مجموعه های مجزا به آسانی با استفاده از Property های اشیا دستیابی داشته باشید ، آورده شده است.

سوالات و پیشنهادات خود را با من در میان بگذارید.

موفق باشید !

داریوش فرخی

داریوش فرخی هستم از سال 92 شروع به یادگیری برنامه نویسی و از سال 93 در بخش برنامه نویسی و تولید محتوای سایت mspsoft.com مشغول هستم. فعالیتم نیز بیشتر در زمینه های برنامه نویسی با سی شارپ و asp.net بوده است. اوقات فراغتم را هم غالبا با تماشای فیلم یا بازی های کامپیوتری پر میکنم .

نوشته‌های مرتبط

دیدگاه‌ها

*
*

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.

    کاربر پاسخ

    با سلام و وقت بخیر سایت شما خوب هست ولی باید بگوییم که 2تا ایراد اساسی از دید بنده دارد
    1- مطالبی که برای آموزش گذاشتین فونتش خیلی کوچیک هست
    2- کدهایی که در درون مطالب برای آموزش بهتر گذاشتین فرمتش بهتره چپ چین باشه حقیقتا من که این موارد را دیدم دوست نداشتم بیشتر از سایت شما استفاده کنم چون خسته کننده هست برای کاربر

      مسعود شریفی پور پاسخ

      سلام
      مورد اول اصلاح شد.
      مورد دوم اصلاح شد.

      ممنون از اینکه ما را نقد میکنید.