تخفیف ویژه

8 کاربرد متفاوت متد Slice برای آرایه‌ها در Javascript

دسته بندی: آموزش
زمان مطالعه: 8 دقیقه
۲۸ آبان ۱۳۹۷

8 کاربرد متفاوت متد Slice برای آرایه‌ها در Javascript

در این مطلب قصد دارم کاربردهای متنوع متد Slice در Javascript که میتونین از اونا بهره ببرید رو بهتون معرفی کنم و شما رو با قدرت اون آشنا کنم.

متد Slice یکی از قدرتمندترین متدهای از پیش تعریف شده در Javascript هست و بصورت متداول از اون استفاده میشه. با سرکار اومدن کتابخانه‌هایی همچون React، اهمیت متد Slice به 2 دلیل بیشتر از قبل شده است:

  1. در برنامه‌نویسی تابعی یا Functional programming و به طور خاص Higher order function بیشتر مواقع با لیستی از داده‌ها سر و کار دارند.
  2. برنامه‌نویسی تابعی به توابع خالص یا Pure function نیاز داره. این توابع توابعی هستند که داده‌های ورودی خودشون رو تغییر نمیدن و باعث به وجود اومدن هیچ Side effect ای نمیشن.

متد Slice برای هر 2 حالت بالا به خوبی جواب میده و نیازهاتون رو برطرف میکنه.

با استفاده از Slice میتونین یک کپی سطحی یا Shallow copy از لیست مورد نظرتون تهیه کنید بدون اینکه لیست اصلی تغییری داده بشه. پس با استفاده از این ویژگی میتونین به راحتی برنامه‎نویسی تابعی رو انجام بدین.

در این مطلب 8 کاربرد متفاوت متد Slice برای آرایه‌ها رو بهتون آموزش میدیم و در آخر این مطلب شما در زمینه Slice یک حرفه‌ای خواهید شد.

نکته :

نباید Slice رو با متد Splice اشتباه بگیرید. این دو مورد کاملا متفاوت هستند و کاربردهای مختلفی دارند. Splice آرایه اصلی رو تغییر میده و در اینجا به درد ما نمیخوره.

فهرست محتوای این مقاله

متد Slice چطوری کار میکنه

قبل از اینکه وارد مثالهای پیشرفته برای متد Slice بشیم، باید موارد ابتدایی این متد رو یاد بگیرید.

همونطور که در مستندات بیان شده است، متد Slice برای آرایه‌ها کاربرد دارد و حداکثر 2 آرگومان رو قبول میکنه. بصورت زیر:

arr.slice([begin[, end]]);

هر 2 آرگومان begin و end از صفر شروع میشن. با استفاده از begin میگیم که از index چندم میخوایم شروع کنیم و با استفاده از end هم میگیم که میخوایم کجا به پایان برسد.

پس با اینکار میتونین یک کپی از اعضای آرایه مورد نظر از begin تا end را تهیه کنیم. همچنین میتونین برای begin و end مقادیر منفی قرار بدین که باعث میشه از آخر شروع بشه.

کاربردهای ساده

4 کاربرد اول، وظایف اصلی متد Slice رو نشون میدن.

کاربرد 1 : کپی ساده

const arr2 = arr.slice();

اگر هیچ آرگومانی برای متد Slice در نظر نگیرید، باعث میشه که یک کپی سطحی از آرایه مورد نظر گرفته میشه و در متغیر arr2 قرار بگیره. در ES2015 به بالا میتونین از Spread operator برای انجام چنین کاری استفاده کنید ولی قبلا برای اینکار از slice استفاده میشد و در جاهایی که babel یا ... ندارید باید از slice استفاده کنید و نمیتونین از ES6 استفاده کنید.

کاربرد 2 : زیر آرایه شروع شده از موقعیت n

زمانی که فقط یک آرگومان رو برای این متد در نظر می‌گیرید، یک زیر آرایه از اون آرگومان تا آخر در اختیار شما قرار داده میشه. فرض کنید که شما قصد دارید با آیتم اول یک آرایه کاری رو انجام بدین و بقیه اعضای اون به جز آیتم اول رو برگشت بدین. همه اینکارها رو میخواید بدون اینکه آرایه اصلی تغییر پیدا کنه، انجام بدین. برای اینکار میتونین بصورت زیر عمل کنید:

function useFirstItem(arr) {
  const usedItem = arr[0];
  // do something with usedItem

  return arr.slice(1);
}

میبینید که برای slice آرگومان 1 قرار داده شده و باعث میشه که از اندیس 1 تا آخر همه آیتمها رو بصورت یک آرایه جدید در اختیار شما قرار بده.

کاربرد 3 : n آیتم آخر آرایه

با استفاده از slice میتونین n آیتم آخر رو از یک آرایه استخراج کنید. برای اینکار از اندیس‌های منفی استفاده میکنیم. برای اینکه 3 آیتم آخر آرایه رو بدست بیاریم بصورت زیر عمل میکنیم:

const last3 = arr.slice(-3);

کاربرد 4 : n آیتم اول آرایه

برای اینکه بتونیم تعداد مشخصی از آیتمها رو از اول آرایه کپی کنیم، باید از آرگومان دوم در متد Slice نیز بهره ببریم. مثلا برای اینکه بخوایم 4 آیتم اول یک آرایه رو بدست بیاریم، میتونیم بصورت arr.slice(0, 4) عمل کنیم:

const first4 = arr.slice(0, 4);

کاربرد 5 : بدست آوردن تعدادی مشخص از موقعیتی دلخواه

فرض کنید که بخوایم از آیتم 3 به بعد، به تعداد 4 آیتم رو انتخاب کرده و مورد استفاده قرار بدیم. برای اینکار میتونیم یک تابع ساده رو بنویسیم که این کار رو برای ما انجام بده:

function pullSegment(arr, begin, length) {
  return arr.slice(begin, begin + length);
}

کار کردن با Object‌های شبیه به آرایه

شما میتونین متد Slice رو برای Array-like objects نیز مورد استفاده قرار بدین. Array-like objects اشیایی هستند که شبیه به آرایه‌ها عمل میکنند ولی در واقع آرایه نیستند. این اشیاء یک ویژگی بنام length دارند و کلیدهای اونا هم بصورت عددی تعریف شده ولی تفاوتی که دارند اینه که متدهای آرایه‌ها برای اونا تعریف نشده. مثلا نمیتونین متد slice رو برای اونا بصورت مستقیم فراخوانی کنید به دلیل اینکه متد slice در Prototype اونا قرار ندارد.

کلمه کلیدی arguments که در توابع مورد استفاده قرار میگیره و لیستی از همه آرگومانها رو در اختیارمون قرار میده و همچنین NodeLists که از Dom API برگشت داده میشه و لیستی از المنتها رو در اختیارمون قرار میده، نمونه‌هایی از Array-like object‌ها هستند.

با استفاده از Slice میتونین کارهای با اهمیتی رو در اینجا انجام بدین.

کاربرد 6 : تبدیل Array-like objects به آرایه

برای اینکه اشیای Array-like رو به آرایه واقعی تبدیل کنید، میتونین از Slice کمک بگیرید. برای اینکار باید از Prototype مربوط به شئ سراسری Array کمک بگیریم. بصورت زیر:

const args = Array.prototype.slice.call(arguments);

با اینکار متد Slice برای arguments فراخوانی میشه و اون رو به یک آرایه واقعی تبدیل میکنه. حالا ممکنه بپرسید که چرا این کار رو کردیم. به خاطر اینکه بتونیم از متدهای آرایه‌ها برای اون استفاده کنیم. مثلا فرض کنیم که این کار رو انجام ندیم و بخوایم از متد map برای arguments استفاده کنیم. بصورت زیر:

function addOne() { 
  return arguments.map(i => i+1); 
}

به نظر میرسه که کار کنه ولی وقتی اون رو اجرا میکنید، با چنین اروری روبرو میشید:

> addOne(1, 2, 3)
TypeError: arguments.map is not a function
    at test (repl:2:18)
    at repl:1:1
    at ContextifyScript.Script.runInThisContext (vm.js:44:33)
    at REPLServer.defaultEval (repl.js:239:29)
    at bound (domain.js:301:14)
    at REPLServer.runBound [as eval] (domain.js:314:12)
    at REPLServer.onLine (repl.js:440:10)
    at emitOne (events.js:120:20)
    at REPLServer.emit (events.js:210:7)
    at REPLServer.Interface._onLine (readline.js:279:10)

این ارور به خاطر این هست که arguments یک شئ شبیه به آرایه هست و متدهای آرایه مثل map و reduce و filter و ... رو نداره. برای اینکه چنین کاری رو انجام بدیم، باید از Slice مجددا کمک بگیریم. بصورت زیر:

function addOne() { 
  return Array.prototype.slice.call(arguments).map(i => i+1); 
}

با اینکار به خروجی مورد نظرتون خواهید رسید:

> addOne(1, 2, 3) 
// [ 2, 3, 4 ]

کاربرد 7 : قرار دادن بقیه آرگومانها در یک آرایه مجزا

فرض کنید که شما یک تابع دارید که تعداد آرگومانهای اون دلخواه هست و تابع میتونه هر تعداد آرگومان که بخواید رو بگیره. با استفاده از Rest Operator در ES6 میتونین به راحتی این کار رو انجام بدین. اما برای مرورگرهای قدیمی که این مورد در اونا پشتیبانی نمیشه، از Slice بصورت زیر استفاده میکنند:

function myFunc(a, b) { 
  const extraArgs = Array.prototype.slice.call(arguments, 2); 
}

اینکار به من اجازه میده که هر تعداد آرگومان که میخوام رو به تابع پاس بدم:

myFunc(1, 2, 3, 4, 5, 6, 7, 8)

با اینکار a === 1 و b === 2 و extraArgs === [3, 4, 5, 6, 7, 8] خواهد شد.

کاربرد 8 : تغییر دادن اندیس مشخص در یک آرایه

یک استفاده متداول و قدرتمند از Slice در برنامه‌نویسی تابعی اینه که بخوایم یک آیتم مشخص در آرایه رو تغییر بدیم و مقدار  اون رو عوض کنیم. شما به راحتی میتونین آیتم مورد نظر در آرایه اصلی رو تغییر بدین ولی در دنیای functional این کار درست نیست و نباید در آرایه اصلی تغییری ایجاد شود.

در عوض شما میتونین با استفاده همزمان از slice و Spread operator مربوط به ES6 این کار رو بدون اینکه در آرایه اصلی تغییری ایجاد کنید، انجام بدین. برای اینکار بصورت زیر عمل میکنیم:

function replaceIdx(arr, index, newVal) {
  return [
    ...arr.slice( 0, index ),
    newVal,
    ...arr.slice( index + 1)
  ],
}

میبینید که slice به راحتی این کار رو برای ما انجام میده.

نتیجه گیری

همونطور که مشاهده میکنید متد Slice خیلی مفید و کاربردی است و با اون میتونین کارهای زیادی رو انجام بدین و هر چه بیشتر به سمت برنامه‌نویسی تابعی حرکت کنید، اهمیت اون براتون بیشتر میشه.

اگر شما هم کاربرد دیگری از متد Slice بلد هستید، خوشحال میشم که در بخش نظرات با سون لرن به اشتراک بزارید.

چه امتیازی به این مقاله می دید؟
نویسنده محمد اسفندیاری
بسیار به طراحی وب علاقمندم و به سرعت در حال یادگیری تمام مباحث پیشرفته هستم و دوست دارم که به دیگران هم یاد بدهم.

نظرات کاربران

اولین دیدگاه این پست رو تو بنویس !

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :