Sequence ها در کاتلین

توی این نوشته سعی میکنم در مورد sequence ها در کاتلین صحبت کنم که به نظرم میرسه یکی از بخش های جالبی هست که کمتر مورد توجه قرار گرفته. سعی میکنم با یک مثال ساده جلو برمفرض کنید لیست اعداد 1 تا 9 رو به این شکل داریم.و حالا میخواهیم به این شکل عمل کنیم که : اقلام لیست رو ضرب در 2 کنیم.از نتیجه یکی کم کنیم.سه قلم اول رو برگردونیم.یعنی کدی که میزنیم به این شکل خواهد شد.نتیجه هم مشخصه . یک لیست به شکل زیر.ولی بیاید با هم فکر کنیم برای این که به این لیست برسیم. چقدر هزینه دادیم.اول کار یک لیست از 1 تا 9 داشتیم . بعدش با فانکشن map ای که نوشته شد به یک لیست 9 تایی دیگه رسیدیم که همه ی اقلامش ضرب در 2 شدن. ( ساخته شدن یک لیست جدید و انجام عمل ضرب روی آیتم های قبلی و ریختن توی لیست جدید )بعد دوباره روی این لیست جدید هم یک عملیات دیگه انجام دادیم که همه ی قلم ها یکی ازشون کم شد و به یک لیست دیگه رسیدیم . (ساخته شدن لیست جدید دوم و انجام عمل تفریق روی آیتم های قبلی و ریختن توی لیست جدید دوم ) و در انتها هم انتخاب سه تا آیتم ابتدای این لیست. (ساخته شدن یک لیست جدید سوم و اضافه شدن سه تا آیتم)عکس زیر رو ببینید.همونطور که مشخصه داریم هزینه ی زیاد و غیر ضروری ای رو پرداخت میکنیم.برای مثال 2 * 8 یکی از اون عملیات هایی هست که هیچ نیازی بهش نداشتیم و توی نتیجه نهایی هم تاثیری نداشته.استفاده از sequencesحالا فرض کنید به جای روش بالا به این شکل عمل کنیم که برای 3 تا قلم اول ( (take(3 ) ، قلم اول رو انتخاب کنیم ، ضربدر 2 ، منهای یک . مجدد برای قلم دوم و به همین ترتیب ... رفتاری شبیه به شکل زیر یعنی به جای اینکه مراحل رو افقی بریم ؛ عمودی بریم.نتیجه این میشه که با تعداد محاسبات کمتر به نتیجه ی یکسانی میرسیم.اما حالا چطور میشه چنین کاری رو انجام داد ؟توی کاتلین یه extension function هست که یک لیست رو میگیره و اون رو به sequence تبدیل میکنه. کد زیر رو ببینید.این کد ، 2تا تفاوت با کد قبلی داره. متدهای ()asSequence و ()toList .که این دو خط باعث ورود و خروج ما از دنیای تفکر sequence ای میشن!البته اون متد های map و take هم که اون وسط وجود دارن ظاهرا تفاوتی با کد قبلی ندارن، ولی در واقع یک تفاوت اساسی دارن ، قبلی ها روی لیست ها یا دقیق تر بگم Iterable ها کار میکنن ولی این یکی ها ، روی Sequence ها . تعریف این دو تا متد رو ببینید. " />Iterable " />Sequence به طور کلی 2 دسته اپراتور برای sequence وجود داره.اپراتور های میانی (Intermediate) یا به قولی "در میان واقع شونده" مثل mapاپراتور های پایانی (terminal) یا "پایانه". مثل toListمیشه گفت رفتاری که که sequence ها دارن یک رفتار lazy طور هست. به این معنی که شما اگر توی کد قبلی از map استفاده میکردین، در لحظه، کد اجرا میشد و خروجیش مشخص بود ولی توی sequence ها همه ی اپراتور های میانی توی یک لیست که operation ها رو نگه میداره اضافه میشن و تا زمانی که به یک اپراتور پایانی مثل ()toList برسیم اجرا نمیشن.شروع sequence هاهمیشه لازم نیست که یک لیست داشته باشیم و با متد ()asSequence بقیه ی عملیات هامون رو شروع کنیم. یعضی وقت ها میشه از همون اول کد sequence ای زد . این جا رو ببینید. متد ()generateSequence با ورودی 1 ، از عدد 1 شروع میشه و برای محاسبه ی عدد بعدی اون رو +2 میکنه.حالا ما میخواهیم که تا 5 بار این کار انجام بشه و در آخر یک لیست برگردونده میشه.یک نکته ی جالب این کد داره ، به هر تعدادی که کاربر مشخص میکنه محاسبات انجام میشه. یعنی میشه گفت تا بی نهایت میتونه مقادیر رو حساب کنه .این هایی که دیدیم تازه چندتا از متدهای ساده ای بود که توی پکیج sequence ها وجود داره. یه نگاه به لینک زیر بندازید.https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/#functionsاستفاده از sequence ها یعنی پرفورمنس بالاتر ؟قطعا خیر! فرض کنید به جای 3 تا آیتم اول لیست همه ی آیتم ها رو میخواستیم. take(9)یعنی تعداد محاسباتی که لازم بود تا به جواب آخر برسیم تقریبا به اندازه ی همون حالت قبلی میشد به اضافه این که لازم بود توی حافظه آبجکت هایی برای نگهداری مراحل نگهداری بشه که این ها یعنی عملا به پرفورمنس بالاتری نمیرسیدیم.جمع بندیمیشه گفت با در نظر گرفتن بعضی از شرایط ، sequence ممکنه بهتر از collection عمل بکنه، فقط همین! البته اگر تعداد اقلام کم باشه خیلی تفاوتی بین استفاده از collection ها (روش اول) و sequence ها نیست. (مثل مثال ما که روی 9 تا آیتم بود).خیلی خوشحال میشم در صورتی که این نوشته رو دوست داشتید ❤️ کنید یا نظرتون را از طریق کامنت برام بنویسید.