آشنایی با متد ()array.flatMap در جاوااسکریپت

آشنایی با متد ()array.flatMap در جاوااسکریپت

فرض کنید یک آرایه از اعداد داریم. چطور می‌تونیم آرایه‌ای جدید از این اعداد بسازیم که تمامی مقادیر در اون دوبرابر شده باشن؟

یکی از تابع های مهم کار با آرایه ها در جاوا اسکریپت، تابع ()array.map هست. در این تابع با پیمایش یه آرایه، آرایه‌ی دیگه‌ای تولید می‌شه که می‌تونه روی مقادیر آرایه‌ی جدید تغییری رو اعمال کند. بنابراین استفاده از ()array.map می‌تونه روش خوبی برای این کار باشه:

const numbers = [0, 3, 6, 11];
const doubledNumbers= numbers.map(number => number * 2);
console.log(doubledNumbers); // logs [0, 6, 12, 22]

متد ()map. بر روی آرایه numbers پیمایش می‌کنه و با اجرای تابع ورودی خودش بر روی اعضا، آرایه ای جدید میسازه که در آرایه جدید، تمام اعداد دوبرابر شدن. برای مواقعی که قصد داشته باشید تمام اعضای آرایه رو دونه به دونه map کنید یا به عبارت دیگه آرایه‌ی حاصل شده، تعداد اعضایی برابر با آرایه اصلی داشته باشه، این متد کارساز هست؛ اما اگر قصد داشته باشیم تمام اعداد آرایه رو دوبرابر کنیم ولی 0 ها رو لحاظ نکنیم چی؟

استفاده از ()array.map به صورت مستقیم ممکن نیست چون این متد همیشه آرایه‌ای با تعداد اعضای برابر با آرایه‌ی اصلی میسازه. اما میشه از ترکیب این متد با متدِ ()array.filter استفاده کرد.

const numbers = [0, 3, 6, 0];

const doubledNumbers= numbers
  .filter(n => n !== 0)
  .map(n => n * 2);

console.log(doubledNumbers); // logs [6, 12]

آرایه حاصل شده شامل اعداد دوبرابر شده و همچنین بدون صفر هست. خب ترکیب این دو متد جواب داد؛ اما آیا راه کوتاه‌تری برای این کار هست؟ بله! به لطف متد ()array.flatMap میتونیم کار هر دو متد رو با یک متد انجام بدیم. بیاین مثال بالا رو با این متد انجام بدیم:

const numbers = [0, 3, 6, 0];

const doubled = numbers.flatMap(number => {
  return number === 0 ? [] : [2 * number];
});

console.log(doubled); // logs [6, 12]

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

متدِ ()array.flatMap یک تابع callback به عنوان آرگومان ورودی دریافت میکنه و یک آرایه map شده‌ی جدید برمی‌گردونه.

const mappedArray=  array.flatMap((item, index, origArray) => { /* ... */ } );

تابع callback سه پارامتر ورودی دریافت میکنه: آیتم فعلی، اندیس و آرایه اصلی. سپس آرایه‌ای برمی‌گردونه که یک مرحله flat شده و آیتم‌های حاصل شده به اون اضافه شدن. برای آشنایی با مفهوم flat کردن آرایه و تابعِ مربوط به اون مطالعه این مقاله رو پیشنهاد میکنم.

همچنین این متد یک پارامتر دوم اختیاری هم دریافت میکنه، مقداری که زمانِ اجرای تابع callback به عنوان this استفاده میشه.

const mappedArray=  array.flatMap((item, index, origArray) => {

     /* ... */ 

    }, thisArg);

یکی از ساده‌ترین کارهایی که میتونید با ()array.flatMap انجام بدید اینه که به وسیله اون آرایه ای که خودش شامل آیتم‌هایی به صورت آرایه هست رو flat کنید:

const arrays = [[2, 4], [6]];

const flatten = arrays.flatMap(item => item);

console.log(flatten); // logs [2, 4, 6]

آرایه اصلی ما شامل آرایه هایی از اعداد بود. با اجرای flatMap آرایه رو flat یا صاف کردیم و در نهایت آرایه ای از اعداد، حاصل کار ما بود. اما این متد جاوا اسکریپت میتونه کارهای بیشتری از صرفاً صاف کردن آرایه انجام بده. با کنترل کردن تعداد آیتم‌های آرایه ای که توسط تابع callback برگردونده میشه میتونیم کارهای جالبی بکنیم، مثلا:

  • با برگردوندن یک آرایه خالی  []، آیتم رو از آرایه بدست اومده حذف کنیم.
  • با برگردوندن یک آرایه با چندین مقدار، آیتم های جدیدی رو اضافه کنیم.
  • با برگردوندن یک آرایه با یک مقدار جدید، آیتم فعلی رو تغییر بدیم.

بیاین با هم یک مثال ببینیم. فرض کنید یک آرایه از اعداد داریم؛ هدف ما اینه که تمام اعداد منفی درون آرایه رو حذف کنیم و همچنین تمام اعداد فرد رو به شکل یک عدد زوج و 1 داشته باشیم.

const numbers = [5, 4, -3, 20, 17, -33, -4, 18];

const result = numbers.flatMap(number => {
    (n < 0) ? [] :
        (n % 2 == 0) ? [n] : [n-1, 1]
});

console.log(result); // [4, 1, 4, 20, 16, 1, 18]

در مثال بالا، درون بدنه‌ی متدِ flatMap اول بررسی میکنیم آیتم فعلی منفی هست یا نه؛ اگر منفی بود یک آرایه خالی برمیگردونیم. این عمل باعث حذف شدن آیتم از آرایه نهایی میشه.

اگر عدد منفی نبود حالا زوج یا فرد بودن اون رو بررسی میکنیم. در صورت زوج بودن، خود عدد رو برمی‌گردونیم اما اگر عدد فرد باشه یک آرایه شامل دو عضو که اولی، یکی کمتر از خود عدد(عددی زوج) و دومی، عدد 1 هست رو برمی‌گردونیم. این کار باعث میشه در آرایه خروجی به جای آیتم فعلی، دو عضو جدید داشته باشیم.

اجازه بدین مثالی که در قسمت بالاتر زدیم رو هم بررسی کنیم. اگه یادتون باشه میخواستیم آرایه ای داشته باشیم که اعداد اون دوبرابر شده باشن و همچنین اعداد 0 از اون حذف شده باشن.

const numbers = [0, 3, 6, 0];

const doubledNumbers= numbers.flatMap(number => {
  return number === 0 ? [] : [2 * number];
});

console.log(doubled); //  [6, 12]

تابع callback در صورتی که آیتم فعلی 0 باشه یک آرایه خالی [] برمی‌گردونه. این یعنی وقتی در نهایت آرایه flat میشه، آرایه خالی هیچ چیزی رو نمایش نمیده و به ازای اون عضوی در آرایه نهایی ظاهر نمیشه.

اگر آیتم فعلی غیر صفر باشه، اون وقت یک آرایه شامل یک عضو که دو برابرِ این آیتم هست برگردونده میشه [number * 2]. در نهایت بعد از flat شدن، این مقدار به آرایه نهایی اضافه میشه.

در یک مثال دیگه، آرایه ای از اعداد داریم. قصد داریم این آرایه رو map کنیم و یک آرایه جدید داشته باشیم که در اون علاوه بر خود عدد، دوبرابر و سه برابر اون هم وجود داشته باشن. نحوه کار به این صورته:

const numbers = [1, 4];

const result = numbers.flatMap(number => {
  return [number, 2 * number, 3 * number];
});

console.log(result);  // logs [1, 2, 3, 4, 8, 12]

 همون طور که می‌بینید این متد در جاوا اسکریپت بسیار کاربردیه و یادگیری اون میتونه تو خیلی از شرایط به شما کمک کنه.

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

از بهترین نوشته‌های کاربران سکان آکادمی در سکان پلاس


online-support-icon