در این تکلیف، شما بیشتر در مورد فیلترها در کاتلین یاد میگیرید. فیلترها یک روش خوب برای گرفتن بخشی از لیست بر اساس شرایط هستند.
گام 1: یک فیلتر بسازید
1. در Hello.kt، با استفاده از ()listOf یک لیست از تزیینات آکواریوم تعریف کنید. شما میتوانید محتوای Hello.kt را جایگزین کنید.
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
2. یک تابع ()main جدید با یک خط برای چاپ تزیینات آکواریوم که با حرف 'p' شروع میشوند بسازید. کد شرط فیلتر داخل آکولاد {} است و وقتی فیلتر به جلو میرود، it به تک تک موردهای لیست مراجعه میکند. اگر عبارت true را برگرداند، فیلتر مورد را شامل شده شده است.
fun main() { println( decorations.filter {it[0] == 'p'}) }
3. برنامه را اجرا کنید، و خروجی پایین را در پنجره Run میبینید:
⇒ [pagoda, plastic plant]
گام 2: مقایسه فیلترهای حریص (eager) و تنبل (lazy)
اکر با فیلترها در سایر زبانها آشنا باشید، شاید فکر کنید که فیلترها در کاتلین حریص هستند یا تنبل. آیا لیست نتایج بلافاصله ساخته میشود، یا وقتی که به لیست دسترسی مییابیم؟ در کاتلین، این بر اساس روشی که نیاز دارید اتفاق میافتد. به طور پیشفرض، filter حریص است، و هر بار که از فیلتر استفاده کنید، لیست ساخته میشود.
برای تنبل ساختن فیلترها، میتوانید از Sequence استفاده کنید، این مجموعهای است که در یک زمان میتواند فقط به یک مورد نگاه کند، با شروع در آغاز و رفتن تا انتها.
1. در Hello.kt، کدتان را برای اختصاص لیست فیلتر شده به یک متغیر با نام eager تغییر دهید.
fun main() { val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot") // eager, creates a new list val eager = decorations.filter { it [0] == 'p' } println("eager: $eager")
2. زیر آن کد، فیلتر را با استفاده از دنباله (sequence) با ()asSequence معین کنید. حالا دنباله را به یک متغیر با نام filtered اختصاص دهید، و آن را چاپ کنید.
// lazy, will wait until asked to evaluate val filtered = decorations.asSequence().filter { it[0] == 'p' } println("filtered: $filtered")
وقتی شما نتیجه فیلتر را به عنوان دنباله بازگردانید، متغیر filtered یک لیست جدید نگه نمیدارد- بلکه یک دنباله از عنصرهای لیست و اطلاعات فیلتر برای اعمال بر عنصرها را نگهمیدارد. وقتی شما به عنصرهای دنباله دست پیدا کنید، فیلتر اعمال شده و نتیجه به شما بازگردانده میشود.
3. ارزیابی دنباله را با تبدیل آن به یک لیست با استفاده ()toList اجرا کنید. نتایج را چاپ کنید.
// force evaluation of the lazy list val newList = filtered.toList() println("new list: $newList")
4. برنامه را اجرا کنید و خروجی را مشاهده کنید.
⇒ eager: [pagoda, plastic plant] filtered: kotlin.sequences.FilteringSequence@386cc1c4 new list: [pagoda, plastic plant]
برای تجسم کردن اینکه چه اتفاقی در دنباله و ارزیابی lazy میافتد، از تابع ()map استفاده کنید. تابع ()map یک تبدیل ساده بر روی هر عنصر دنباله اعمال میکند.
5. با دکورهای لیست قبل، یک تبدیل با ()map بسازید که هیچ کاری انجام ندهد، و فقط عنصری که واگذار شد را برگرداند. یک ()println برای هر بار که یک عنصر دست پیدا میکنید اضافه کنید، و دنباله را یه یک متغیر با نام lazymap اختصاص دهید.
val lazyMap = decorations.asSequence().map { println("access: $it") it }
6. متغیر lazymap را چاپ کنید، با استفاده از ()first اولین عنصر lazymap را چاپ کنید، و lazymap تبدیل شده به یک List را هم چاپ کنید.
println("lazy: $lazyMap") println("-----") println("first: ${lazyMap.first()}") println("-----") println("all: ${lazyMap.toList()}")
7. برنامه را اجرا کنید، و خروجی را مشاهده کنید. چاپ کردن lazymap فقط منبع دنباله را چاپ میکند-()println داخلی صدا زده نمیشود. چاپ کردن عنصر اول فقط به عنصر اول دست یابی دارد. تبدیل دنباله به یک List به همه عنصرها دستیابی دارد.
⇒ lazy: kotlin.sequences.TransformingSequence@5ba23b66 ----- access: rock first: rock ----- access: rock access: pagoda access: plastic plant access: alligator access: flowerpot all: [rock, pagoda, plastic plant, alligator, flowerpot]
8. با استفاده از فیلتر اصلی یک دنباله جدید پیش از اعمال map بسازید. نتایج را چاپ کنید.
val lazyMap2 = decorations.asSequence().filter {it[0] == 'p'}.map { println("access: $it") it } println("-----") println("filtered: ${lazyMap2.toList()}")
9. برنامه را اجرا کنید و خروجی افزوده را مشاهده کنید. با گرفتن عنصر اول، ()println داخلی فقط برای عنصرهایی که به آن دسترسی پیدا شد صدا زده میشود.
⇒ ----- access: pagoda access: plastic plant filtered: [pagoda, plastic plant]