سلام و عرض ادب خدمت کاربران عزیز در این جلسه قصد داریم با اپراتورهای Set در LINQ و کاربرد آن ها آشنا شویم.
به طور کلی این اپراتورها برای بررسی اجتماع یا اشتراک یا تفاوت بین مجموعه ها استفاده می شود که در ادامه هر یک را به طور کامل با استفاده از مثال بررسی خواهیم کرد.
اپراتورهای Set به چهار بخش تقسیم بندی می شوند که خلاصه ی کاربرد هر یک در جدول زیر نشان داده شده است:
UnionIntersectExcept| کاربرد | نام اپراتور |
| دو یا چند مجموعه را به یک مجموعه با عضوهای غیر تکراری تبدیل می کند (عمل اجتماع) | Union |
| بر روی دو یا چند مجموعه عمل اشتراک گیری را انجام می دهد و عضو(های) مشترک را مشخص می کند | Intersect |
| بر روی یک مجموعه عمل و عضو های تکراری را حذف می کند. | Distinct |
| عضوی (اعضایی) که در مجموعه اول موجود ولی در مجموعه ی دوم موجود نیستند را بر می گرداند (عضو متفاوت را مشخص می کند). | Except |
همان طور که از نام این متد مشخص است عمل اجتماع (نماد:U) را پیاده سازی می کند که کاملا مشابه با مبحث اجتماع در ریاضیات است.
به تصویر زیر دقت کنید:

در شکل بالا مجموعه ی اول، آرایه ای به صورت [a,b,c,d] و مجموعه ی دوم [a,b,e,f] است که اجتماع آن ها به صورت مجموعه ی [a,b,c,d,e,f] نشان داده شده است.
الگوی کلی استفاده از Union به صورت زیر است:
var result = count1.Intersect(count2);
منظور از count1 و count2 دو مجموعه ی مختلف از داده ها می باشد.
برای درک بهتر موضوع به مثال زیر توجه کنید:
using System;
using System.Linq;
namespace Linqtutorials
{
class Program
{
static void Main(string[] args)
{
string[] count1 = { "UK", "Australia", "India", "USA" };
string[] count2 = { "India", "Iran", "UK", "China" };
var result = count1.Union(count2).OrderBy(x =>x);
foreach (var item in result)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
}
در این مثال دو آرایه از جنس string با عناصر مختلف تعریف شده است. دو مجموعه دارای تعدادی عناصر تکراری و غیر تکراری هستند. با استفاده از متد Union بر روی دو آرایه عمل اجتماع را پیاده سازی کرده ایم که نتیجه ی آن در result ذخیره می شود و داده ها با استفاده از یک حلقه قابل دستیابی خواهد بود.
در این مثال برای آشنایی بیشتر با کاربرد متدها در کنار هم از متد OrderBy برای مرتب سازی عناصر بر اساس ABC استفاده شده است. برای درک کاربرد آن می توانید OrderBy را حذف کرده و تفاوت خروجی را مشاهده کنید.
مانند بخش های قبلی کد بالا را به صورت Query پیاده سازی می کنیم که به صورت زیر می باشد:
var result = from x in count1.Union(count2) orderby x select x;
به نحوه ی کاربرد Union و OrderBy دقت کنید.
سوال: آیا (count1.Union(count2 با (count2.Union(count1 تفاوت دارد.
جواب: خیر، کاربرد کلی Union پیاده سازی عمل اجتماع است و مهم نیست که بر روی کدام مجموعه Union فراخوانی شده و کدام مجموعه به عنوان پارامتر به آن ارسال شده است. پس خروجی هر دو مشابه خواهد بود.

از این متد برای مشخص کردن عناصر مشترک بین دو یا چند مجموعه استفاده می شود در واقع این متد عناصر مشترک را بر می گرداند که شبیه به عملیات اشتراک در ریاضیات است.

به تصویر زیر دقت کنید:
طبق عکس بالا دو مجموعه ی [a,b,c,d] و [a,b,e,f] وجود دارد که با استفاده از متد Intersect می توان مجموعه ای جدید تولید کرد که اعضای آن عناصر مشترک در دو مجموعه ی قبل هستند.
الگوی استفاده از آن به صورت زیر است:
var result = count1.Intersect(count2);
برای آشنایی بیشتر با کاربرد آن به مثال زیر دقت کنید:
using System;
using System.Linq;
namespace Linqtutorials
{
class Program
{
static void Main(string[] args)
{
string[] count1 = { "UK", "Iran", "India", "USA" };
string[] count2 = { "India", "Canada", "Brazil", "Iran" };
var result = count1.Intersect(count2);
foreach (var item in result)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
}
این مثال کاملا مشابه مثال مربوط به Union است فقط در اینجا به جای عمل اجتماع با استفاده از متد Intersect عمل اشتراک پیاده سازی شده است. در نتیجه ی آن اعضایی که در هر دو آرایه وجود دارند به عنوان خروجی در نظر گرفته می شوند.
پیاده سازی آن با روش Query به صورت زیر است:
var result = from x in count1.Intersect(count2) select x;

لازم به ذکر است که در این متد مانند متد Union تفاوتی ندارد که کدام مجموعه متد را فراخوانی کرده و کدام مجموعه به عنوان پارامتر به آن ارسال شده در هر صورت خروجی یکسان خواهد بود.
این متد برای حذف عناصر تکراری در یک مجموعه استفاده می شود که کاملا شبیه به Distinct در زبان SQL است.
به تصویر زیر توجه بفرمایید:

همان طور که در عکس بالا مشاهده می کنید مجموعه ی [a,b,c,c,d,e] دارای عضو تکراری است اما بعد از استفاده از متد Distinct عضو تکراری از مجموعه حذف شده و مجموعه ای جدید به عنوان خروجی در نظر گرفته شده است.
الگوی استفاده از این متد به صورت زیر است:
var result = numbers.Distinct();
برای آشنایی بیشتر با متدDistinct به مثال زیر دقت کنید:
using System;
using System.Linq;
using System.Collections.Generic;
namespace Linqtutorials
{
class Program
{
static void Main(string[] args)
{
string[] countries = { "UK", "UK", "Iran", "INDIA", "india", "USA", "USA", "iran" };
var result = countries.Distinct();
foreach (var item in result)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
}
در اینجا یک آرایه از string داریم که دارای عناصر تکراری است. به اعضای آرایه دقت کنید عناصری که تکراری هستد با حروف کوچک و بزرگ نوشته شده اند.
بازنویسی کد با روش Query به صورت زیر است:
var result = (from x in countries select x).Distinct();

شکل بالا به عنوان خروجی نشان داده شده است همان طور که مشاهده می کنید متد Distinct به بزرگ یا کوچک بودن حروف حساس است و فقط عناصری را حذف می کند که دقیقا مثل هم نوشته شده باشند. (از نظر کوچک و بزرگ بودن حروف)
از این متد برای بازگرداندن اعضایی از مجموعه ی اول که در مجموعه ی دوم موجود نیست استفاده می شود.
برای درک بهتر به شکل زیر توجه کنید:

در اینجا مجموعه ی [a,b,c,d,e] اول و مجموعه ی [a,b,e,f]، دوم فرض شده است. می بینید که در اولی عضو C وجود دارد اما در دومی موجود نیست. Except دقیقا عنصر یا عناصری را به عنوان خروجی در نظر می گیرد که در مجموعه ی اول موجود ولی در مجموعه ی دوم موجود نباشد.
الگوی کلی استفاده از آن به صورت زیر است:
var result = arr1.Except(arr2);
سوال: آیا در متد Except مانند متدهای Intersect و Union فرقی دارد که کدام مجموعه متد را فراخوانی کرده و کدام مجموعه به عنوان پارامتر در آن قرار گرفته است؟
جواب: بله، در واقع در زمان استفاده از این متد مجموعه ای که این متد را فراخوانی کرده به عنوان مجموعه ی اول و مجموعه ای که به عنوان پارامتر به متد وارد می شود، مجموعه ی دوم تلقی می شود.
برای درک بهتر به مثال زیر توجه کنید:
using System;
using System.Linq;
using System.Collections.Generic;
namespace Linqtutorials
{
class Program
{
static void Main(string[] args)
{
string[] arr1 = { "Olivia", "Jack", "Oscar", "Emily" };
string[] arr2 = { "Olivia", "Freddie", "Jack", "Oscar" };
var result = arr1.Except(arr2);
foreach (var item in result)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
}
در این مثال دو آرایه تعریف شده که هر آرایه دارای 3 عضو مشابه با آرایه ی دیگر و یک عضو متفاوت است. در اینجا arr1 مجوعه ی اول و arr2 مجموعه ی دوم در نظر گرفته شده است. حالا کد را در IDE خود نوشته و خروجی را مشاهده کنید. خواهید دید که خروجی کلمه ی Emily خواهد بود که در arr1 وجود دارد ولی در arr2 موجود نیست.
حالا تغییر زیر را در کد اعمال و بار دیگر خروجی را مشاهده کنید:
var result = arr2.Except(arr1);
همان طور که می بینید خروجی حالت دوم، کلمه ی Freddie است که دلیل آن کاملا مشخص است چون در اینجا مجموعه ی arr2 متد را فراخوانی کرده و arr1 به عنوان پارامتر به متد ارسال شده است. در واقع متد Except عضوی (اعضایی) است که در arr2 موجود بوده ولی arr1 موجود نیست و آن به عنوان خروجی در نظر می گیرد.
برای نوشتن کد به روش Query کد را به این صورت تغییر می دهیم:
var result = from x in arr1.Except(arr2) select x;
توجه: برای استفاده از اپراتورهای Set بر روی کلاس ها با Properties های مختلف لازم است تغییراتی در کلاس و روش مقایسه انجام شود در غیر این صورت خروجی مناسب نخواهد بود.
این بخش از آموزش به پایان رسید. در قسمت بعدی آموزش با اپراتورهای joining در LINQ آشنا خواهیم شد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.