سه روش برای چرخش آرایه ها در جاوا اسکریپت – راهنمای کاربردی


یکی از مسائلی که به طور مکرر در زمان برنامهنویسی در جاوا اسکریپت با آن مواجه میشویم، بحث چرخش آرایهها است. در این مقاله سه روش برای چرخش آرایه ها در جاوا اسکریپت معرفی میکنیم. به مسئله زیر توجه کنید:
در مسئله فوق خواسته شده است که یک آرایه مفروض به اندازه K مرتبه به سمت راست چرخش پیدا کند که K عددی غیر منفی است.
راهحل نخست: استفاده از while و چرخش با ()pop. و ()unshift.
سادهترین روش برای چرخش آرایه، استفاده از متد ()pop. جاوا اسکریپت است که به صورت تخریبی عناصر را حذف میکند و آخرین عنصر آرایه را بازگشت میدهد. این متد در ترکیب با متد ()unshift. که به صورت تخریبی عناصر را به ابتدای آرایه اضافه میکند موجب ایجاد راهحلی برای مسئله مورد بررسی میشود.
طرز کار آن به صورت زیر است:
در این مسئله ما میخواهیم عملیات را به میزان k بار اجرا کنیم. این کار با استفاده از تنظیم یک حلقه while میسر است:
در خط 2 کد فوق یک شمارنده تنظیم میکنیم که مقدار اولیه آن صفر است. در انتهای هر حلقه (در خط 5) مقدار شمارنده را یک واحد افزایش میدهیم. در خط 3 اعلام میکنیم که «تا وقتی شمارنده کمتر از تعداد دفعات مورد نظر برای اجرای حلقه است به اجرای حلقه ادامه بده.»
نکته: میدانیم که حلقه را با مقدار اولیه صفر به جای یک آغاز کردهایم. اگر میخواهید آن را از 1 آغاز کنید، در این صورت در خط 3 باید به جای while i < k، کدی به صورت while i <= k بنویسید. این راهحل پاسخ مورد نظر را ارائه میکند، اما کُند است:
راهحل دوم: استفاده از ()splice. به جای ()pop.
با این که ()splice. احتمالاً کمی سریعتر از ()pop. عمل میکند، اما اختلاف آنها ناچیز است و در مواردی حتی ممکن است دومی سریعتر اجرا شود. زمانی که یک آیتم را از یک آرایه حذف میکنید، آیتمهای پس از آن باید به سمت جلو حرکت کنند تا جای آیتم خالی را در حافظه پر کنند. بسته به میزان بزرگی آرایه، این کار میتواند منجر به کندی اجرا شود. چون باید همه عناصر آرایه در حافظه جابجا شوند و به این ترتیب باید هر بار که آرایه تغییر مییابد، همه اندیسها از نو محاسبه شوند.
اگر همیشه آیتم آخر را از آرایه بردارید، دیگر آیتم بعدی نخواهد بود که بخواهد اندیسگذاری مجدد شود و از این رو مرحله اندیسگذاری مجدد حذف میشود. با تعریف ()pop. همواره آخرین آیتم برداشته میشود از این رو به قدر کافی سریع است. ()splice. میتواند آیتمها را از هر کجای آرایه انتخاب کند. از این رو زمانی که هر چیزی به جز آیتم آخر را انتخاب کنید، کندتر عمل میکند. ()splice. دو آرگومان میگیرد:
- اندیسی که میخواهیم از آن آیتم را حذف کنیم. با استفاده از اعداد 1-، 2- میتوانیم آیتم آخر، ماقبل آخر و همین طور تا اول را مورد ارجاع قرار دهیم.
- تعداد آیتمهایی که باید حذف شود. اگر آرگومان دوم ارائه نشده باشد، splice به صورت خودکار همه عناصر را با آغاز از اندیس ارائه شده تا انتهای آرایه حذف میکند.
این یک روش تخریبی است که آرایه اصلی را تغییر میدهد. اگر میخواهید یک روش غیر تخریبی داشته باشید، از متد ()slice. استفاده کنید که آرگومانهای متفاوتی میگیرد. برای کسب اطلاعات بیشتر در مورد این دو متد و تفاوتهای آن به این مطلب مراجعه کنید:
طرز کار ()splice. به صورت زیر است:
در مورد مسئله مورد بررسی میتوانیم از آن به صورت زیر استفاده کنیم:
اما این راهحل متأسفانه سریعتر نیست:
راهحل سوم: بهینهسازی برای سناریوهای مختلف
تا به اینجا رویکردهای کدنویسی ما این بود که هر بار یک عنصر را از آرایه برداریم و آن را به ابتدای آرایه بعدی الحاق کنیم. در این رویکرد مهم نیست که طول آرایه کوتاه یا بلند است. طرز کار آن در صورتی که بخواهیم 1 آیتم یا 1 میلیون آیتم را برداریم یکسان است.
میتوان با مناسبسازی این روش برای سناریوهای مختلف آن را بهینهسازی کرد. اگر آرایهای با 100 عنصر داشته باشم و k برابر با 90 باشد چطور؟ اگر 90 بار آخرین آیتم را برداریم و آن را به ابتدای آرایه دیگر الحاق کنیم باید 90 بار آرایه را اندیسگذاری مجدد کنیم و این عدد بسیار بزرگی است.
اما میتوانیم با استفاده از متد ()splice. تنها k آیتم را از انتها آرایه برداریم و آنها را به ابتدای آرایه دیگر به صورت بلوکی اضافه کنیم. طرز انجام آن به صورت زیر است:
در زمان انجام این کار باید به برخی نکات توجه داشته باشیم:
- ما از K– برای برش دادن k آیتم آخر آرایه با متد ()splice. استفاده میکنیم.
- nums.splice(-k) یک آرایه بازگشت میدهد. برای افزودن عناصر آن آرایه به ابتدای nums (به جای خود آرایه) از عملگر اسپرد زیر استفاده میکنیم:
...nums.splice(-k)
اجرای این کد نتیجه زیر را در پی خواهد داشت:
اما این کد کار نمیکند:
دلیل آن این است که حالت استثنایی که تعداد دفعات لازم برای چرخش یعنی k بزرگتر از طول آرایه باشد را در نظر نگرفتهایم. برای مدیریت این حالت استثنایی میتوانیم گزاره if/else دیگری اضافه کنیم.
توجه کنید که گزاره else از کد راهحل دوم استفاده میکند. این کد سریعتر اجرا میشود:
به این ترتیب به پایان این مقاله میرسیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- آموزش JavaScript ES6 (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- کار با JSON در جاوا اسکریپت — راهنمای کاربردی
- معرفی جاوا اسکریپت ناهمگام — به زبان ساده
==