با سلام خدمت کاربران عزیز در این بخش قصد داریم با Filtering Operator (اپراتور های فیلتر) در LINQ آشنا شویم و مثال های متعددی از آن را بررسی کنیم.
Filtering Operator چیست؟
در زبان C# برای فیلتر کردن اطلاعات خروجی از Filtering Operator (اپراتور های فیلتر) استفاده می شود.
در LINQ دو نوع متد فیلتر وجود دارد که به شرح زیر می باشند:
کاربرد |
نام متد |
از این متد برای انتخاب مقادیری از لیست بر اساس شرایط اعمال شده استفاده می شود |
Where |
از این متد برای استخراج نوع داده ای مشخص از لیست استفاده می شود |
OfType |
کاربرد متد Where
فیلتر Where
مشخص می کند که اطلاعات استخراج شده از منبع داده دارای چه شرطی باشند. بدین صورت که اطلاعات دریافتی باید در شرط موجود در متد where
صدق کنند تا فیلتر اجازه ی عبور آن را صادر کند که کارکرد آن دقیقا مانند Where
در زبان SQL است.
الگوی کلی استفاده از Where
به صورت زیر می باشد:
|
IEnumerable<string>result=countries.Where(x=>x.StartsWith("A"));
|
برای آشنایی با کاربرد این متد به مثال های زیر توجه کنید:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
usingSystem;
usingSystem.Linq;
usingSystem.Collections.Generic;
namespaceLinqtutorials
{
classMainClass
{
staticvoidMain(string[]args)
{
string[]countries={"India","Iran","USA","Argentina","Peru","China"};
IEnumerable<string>result=countries.Where(s=>s.StartsWith("I"));
foreach(stringitem inresult)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
}
}
|
در این مثال یک آرایه string
که در بردارنده ی نام کشور ها است ایجاد و در ادامه با استفاده از Where
برای استخراج داده از آن، شرطی در نظر گرفته شده که فقط اعضایی انتخاب می شوند که اول نام آن ها I باشد. سپس این اعداد در متغیرresult
ذخیره می شوند.
طبق روال قبل این مثال را با روش Query بازنویسی می کنیم که لازم است عبارت جلوی result
را به صورت زیر تغییر دهید:
|
IEnumerable<string>result=fromxincountries
wherex.StartsWith("A")
selectx;
|
مثال اول قسمت قبل را در نظر بگیرید که با استفاده از متد select
نام دانشجو و معدل آن را از لیست خارج و در خروجی چاپ کردیم، حالا قصد داریم فقط نام دانشجوهایی که معدل آن ها بالا تر از 15 است در خروجی نشان دهیم برای این منظور کد را به صورت زیر تغییر می دهیم:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
namespaceLinqtutorials
{
classMainClass
{
staticvoidMain(string[]args)
{
List<Student>stuList=newList<Student>()
{
newStudent(){ID=100,Name="amir",Age=23,Average=16.25},
newStudent(){ID=101,Name="reza",Age=22,Average=12.3},
newStudent(){ID=102,Name="sara",Age=22,Average=12},
newStudent(){ID=103,Name="hassan",Age=24,Average=18},
newStudent(){ID=104,Name="mina",Age=21,Average=17.11},
};
varStudentList=stuList.Where(x=>x.Average>15);
Console.WriteLine("name"+"\t"+"average");
foreach(Student item inStudentList)
{
Console.WriteLine("{0}"+"\t"+"{1}",item.Name,item.Average);
}
Console.ReadKey();
}
}
publicclassStudent
{
publicintID{get;set;}
publicstringName{get;set;}
publicintAge{get;set;}
publicdoubleAverage{get;set;}
}
}
|
کد را اجرا و خروجی آن را مشاهده کنید و دقت کنید فقط رکوردهایی که معدل آن ها بالای 15 بوده در خروجی نشان داده شده اند. به عبارت Lambda نوشته شده در where
توجه کنید. متغیر x از نوع کلاس Student
و خروجی آن از نوعbool
است. با هدایت موس بر روی where
به راحتی می توانید از صحت این موضوع مطمئن شوید.
برای بازنویسی به صورت Query، کد را به این شکل تغییر می دهیم:
|
varStudentList=from stu instuList
where stu.Average>15
select stu;
|
همان طور که تا اینجا متوجه شدید نوشتن کد به صورت Query ساده تر بوده و تا حدودی شبیه به کدهای SQL است، اما همیشه اینطور نخواهد بود و ممکن است در برنامه های بزرگتر روش Query کمی پیچیده و مشکل به نظر برسد که در آموزش های آینده شاهد این موضوع خواهیم بود.
خروجی مثال دوم – کاربرد Where
سوال: آیا می توان در LINQ از شروط چندگانه استفاده کرد؟
جواب: بله. LINQ از شروط چندگانه پشتیبانی می کند و این عملیات به راحتی قابل پیاده سازی است.
به مثال زیر توجه کنید:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
usingSystem;
usingSystem.Linq;
usingSystem.Collections.Generic;
namespaceLinqtutorials
{
classMainClass
{
staticvoidMain(string[]args)
{
string[]countries={"India","Iran","USA","Argentina","Peru","China"};
IEnumerable<string>result=countries.Where(s=>s.StartsWith("I")&s.EndsWith("n"));
foreach(stringitem inresult)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
}
}
|
در اینجا تعین کرده ایم که فقط نام کشور هایی در خروجی نمایش داده شود که شروع با I و پایان آنها با n (کوچک) باشد. توجه داشته باشید که متدهای استفاده شده در where
به کوچک و بزرگ بودن حروف حساس هستد. کد را اجرا و خروجی را مشاهده کنید.
بازنویسی این مثال به روش query به صورت زیر است:
|
IEnumerable<string>result=fromxincountries
wherex.StartsWith("I")
wherex.EndsWith("n")
selectx;
|
کاربرد متد OfType
با استفاده از این متد می توان نوع مشخصی از داده را از منبع اطلاعاتی واکشی کنیم، به طوری که بقیه ی عناصر نادیده گرفته شوند.
الگوی استفاده از آن به صورت زیر می باشد:
|
IEnumerable<string>result=obj.OfType<string>();
|
توجه کنید که نوع داده ای که قرار است آن را استخراج کنید باید در <>
قرار گیرد.
برای آشنایی با این متد به مثال های زیر توجه کنید:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem.Linq;
namespaceLinqtutorials
{
classProgram
{
staticvoidMain(string[]args)
{
ArrayList obj=newArrayList();
obj.Add("Iran");
obj.Add("USA");
obj.Add(1);
obj.Add(true);
obj.Add(55.6);
obj.Add("UK");
obj.Add("India");
IEnumerable<string>result=obj.OfType<string>();
foreach(varitem inresult)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
}
|
در این مثال یک ArrayList
تعریف شده که هر نوع داده ای را می توان در آن وارد کرد. حالتی را در نظر بگیرید که فقط به نوع مشخصی از داده های داخل یک منبع نیاز داریم، مثلا نوع string.
برای این منظور متد OfType
در LINQ معرفی شده است. در این مثال نوع های مختلفی از داده در ArrayList
وارد شده اند و ما قصد داریم اعضایی را که نوع آن ها string است، استخراج کنیم.
برای نوشتن با روش Query کد به این صورت تغییر می کند:
|
IEnumerable result=fromxinobj.OfType<int>()
selectx;
|
خروجی در حالت انتخاب نوع داده ی string
به شکل زیر است:
خروجی مثال چهارم – کاربرد OfType
مثال جالب زیر را در نظر بگیرید:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem.Linq;
namespaceLinqtutorials
{
classMainClass
{
staticvoidMain(string[]args)
{
ArrayList persons=newArrayList()
{
newStudent(){ID=100,Name="amir",Age=23,Average=16.25},
newStudent(){ID=101,Name="reza",Age=22,Average=12.3},
newStudent(){ID=102,Name="sara",Age=22,Average=12},
newStudent(){ID=103,Name="hassan",Age=24,Average=18},
newStudent(){ID=104,Name="mina",Age=21,Average=17.11},
newEmployee(){ID=2000,Name="nader",Gender="Male",HoursWorked=150},
newEmployee(){ID=2000,Name="javad",Gender="Male",HoursWorked=177},
newEmployee(){ID=2000,Name="neda",Gender="Female",HoursWorked=110},
newEmployee(){ID=2000,Name="arash",Gender="Male",HoursWorked=300},
newEmployee(){ID=2000,Name="zahra",Gender="Female",HoursWorked=160},
newEmployee(){ID=2000,Name="amin",Gender="Male",HoursWorked=100}
};
IEnumerable<Employee>personsList=persons.OfType<Employee>().Where(x=>x.HoursWorked>140&x.Gender.Equals("Female"));
foreach(Employee item inpersonsList)
{
Console.WriteLine("{0}"+"\t"+"{1}"+"\t"+"{2}",item.Name,item.Gender,item.HoursWorked);
}
Console.ReadKey();
}
}
publicclassStudent
{
publicintID{get;set;}
publicstringName{get;set;}
publicintAge{get;set;}
publicdoubleAverage{get;set;}
}
publicclassEmployee
{
publicintID{get;set;}
publicstringName{get;set;}
publicstringGender{get;set;}
publicintHoursWorked{get;set;}
}
}
|
در این مثال دو کلاس Student
و Employee
تعریف شده که هر کدام دارای فیلد های مشخصی هستد. در کلاس Main
یک ArrayList
تعریف شده و درون آن با اشیای هر دو کلاس پر شده است. هدف اول ما در این مثال استخراج داده هایی از جنس کلاس Employee
است که با استفاده از متد OfType
قابل انجام است. حال قصد داریم فقط کارمندانی که ساعات کاری آن ها بیشتر از 140 ساعت و جنیست آن ها زن است را در خروجی نمایش دهیم که این کار با استفاده شرط داخلWhere
قابل پیاده سازی است.
خروجی مثال بالا به صورت زیر است:
تمرین: مانند جلسه ی قبل سعی کنید این مثال را با استفاده از روش Query بنویسید و خروجی را با خروجی روش اول مقایسه کنید. بدیهی است که خروجی باید یکسان باشند.
جواب تمرین:
|
IEnumerable<Employee>personsList=from person inpersons.OfType<Employee>()
where person.HoursWorked>140
where person.Gender.Equals("Female")
select person;
|
این بخش از آموزش هم به پایان رسید.
موفق باشید.
منبع: روکسو