متد های map و filter در جاوا اسکریپت

محمدامین سعیدی راد
1400/09/14
1557
متد های map و filter در جاوا اسکریپت

متد های map و filter در جاوا اسکریپت

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

شباهت های بین map و filter

متد های map و filter در جاوا اسکریپت

هر کدام از متد های map و filter در حالت عادی یک فانکشن به عنوان ورودی از ما دریافت کرده و آن را به ازای تعداد آیتم های آرایه تکرار می کنند. پس در ساده ترین حالت یک حلقه (loop) به حساب میان.
به کد های زیر توجه کنید:

let scores = [12, 90, 14, 72, 89, 51]

scores.map(function () {
console.log('SabzLearn')
})

scores.filter(function () {
console.log('SabzLearn')
})

در هر دو تکه کد های بالا، مقدار SabzLearn به تعداد 6 بار (length ارایه scores) در console نمایش داده می شود.
پس هر دوی آن ها در حالت عادی یک فانکشن را به ازای تعداد آیتم های آرایه مورد نظرمان تکرار می کنند، اما کاربرد کاملا متفاوتی دارند.

شباهت بعدی آن ها در ورودی هایشان است. همان طور که متوجه شدید، متد های map و filter یک فانکشن را به عنوان ورودی دریافت کرده و آن را به ازای تعداد آیتم های داخل آرایه تکرار می کند.
یعنی در مثال بالا، کد console.log یک بار به ازای 12، یک بار به ازای 90، یک بار به ازای 14 و … در نهایت یک بار هم به ازای 51 اجرا می شود.
حال ممکن است در هر دفعه تکرار، قصد داشته باشیم به خود مقدار آن آیتم از آرایه (یعنی 12، 90 و …) نیز داخل فانکشن دسترسی داشته باشیم.
در این حالت یک ورودی با اسم دلخواه به فانکشن ارسال می کنیم و در هر بار تکرار کد های داخل فانکشن، داخل همان ورودی به مقدار آیتم فعلی آرایه دسترسی داریم.
یعنی دفعه اول که تابع اجرا می شود، مقدار 12 از آرایه scores به تابع پاس داده می شود، در اجرای بعدی مقدار 90 و … تا زمانی که به آخرین مقدار از آرایه برسیم. (اگر قسمتی از توضیحات برای شما مبهم بود، لطفا به ویدئوی همین مقاله مراجعه کنید)

به عنوان مثال:

let scores = [12, 90, 14, 72, 89, 51]

scores.map(function (score) {
console.log(score) // 12 90 14 72 89 51
})

scores.filter(function (score) {
console.log(score) // // 12 90 14 72 89 51
})

همان طور که مشاهده می کنید، یک ورودی به اسم score به فانکشن ورودی map و filter ارسال کرده ایم. در دفعه اول که فانکشن اجرا می شود، آیتم اول از آرایه scores (مقدار 12) در ورودی score قرار گرفته و داخل فانکشن مورد استفاده قرار می گیرد. در دفعه دوم اجرای فانکشن، آیتم بعدی آرایه scores (مقدار 90) به آن ارسال می شود و داخل فانکشن همین ورودی (مقدار 90) log گرفته می شود.

پس ما می توانیم در هر دفعه اجرای فانکشن ورودی متد های map و filter، می توانیم به تک تک آیتم های آرایه مورد نظر دسترسی داشته باشیم.

آموزش جاوا اسکریپت

کاربرد متد map در جاوا اسکریپت

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

فرض کنید میوه های سمت چپ همان آیتم های آرایه هستند و ما قصد داریم تک تک آیتم های آرایه را قاچ کنیم. یعنی عمل قاج کردن را برای تک تک ایتم های آرایه انجام بدیم (تکرار کنیم).

به عنوان مثال یک آرایه ای به اسم scores (امتیازها) دارید که 5 عدد داخلش ذخیره شده و شما می خواهید تک تک امتیاز ها را در عدد 2 ضرب کنید. در همچین حالتی از متد map در جاوا اسکریپت استفاده می کنیم.
دقیقا مثل تکه کد زیر:

scores.map(function (score) {
return score * 2
})

به همین راحتی می توانیم تک تک آیتم های آرایه scores را در عدد 2 ضرب کنیم. اما همان طور که از کد بالا مشخص است، داخل فانکشن دیتایی return می شود اما نتیجه آن را در هیچ متغیری ذخیره نکردیم! یعنی نتیجه و خروجی متد map رو هواست!
برای همین باید خروجی متد map را داخل متغیری قرار دهیم.
طبق کد زیر عمل می کنیم:

let scores = [12, 90, 14, 72, 89, 51]

let doubleNumbers = scores.map(function (score) {
    return score * 2
})

console.log(doubleNumbers) // [24, 180, 28, 144, 178, 102]

همان طور که مشاهده می کنید، خروجی متد map را داخل متغیری به اسم doubleNumbers ذخیره کرده و در خط بعدی آن را log گرفتیم.
در اصل متد map آرایه scores را دستکاری نمی کند. بلکه تک تک آیتم های آرایه scores را در عدد 2 ضرب کرده و نتیجه آن ها را داخل آرایه ای ذخیره کرده و return می کند.
به همین راحتی یک آرایه ای داریم به اسم doubleNumbers که آیتم های آن ضرب آیتم های آرایه score در عدد 2 هستند.

کاربرد متد filter در جاوا اسکریپت

همان طور که از معنی کلمه filter مشخص است، زمانی از متد filter استفاده می کنیم که قصد داشته باشیم چند مورد از آیتم های آرایه را تحت شرایط دلخواه و خاصی فیلتر کنیم (یعنی برداریم).
به تصویر زیر دقت کنید:

متد های map و filter در جاوا اسکریپت

فرض کنید میوه های سمت چپ همان آیتم های آرایه مورد نظرمان هستند و ما می خواهیم میوه هایی از آرایه که رنگ آن ها قرمز هستند را فیلتر کنیم (برداریم). در همچین مواقعی از متد filter در جاوا اسکریپت استفاده می کنیم.

سینتکس و نحوه نوشتن متد filter دقیقا مثل متد map است که یک فانکشن را به عنوان ورودی دریافت کرده و تک تک آیتم های آرایه مورد نظرمان را نیز به عنوان ورودی فانکشن در نظر می گیرد و سپس آن ها را (آیتم ها) با شرط داخل فانکشن مقایسه می کند و هر کدام از آن ها که شرط مورد نظر ما برای فیلتر شدن را داشتند، آن ها دقیقا مثل map در قالب یک آرایه در اختیار با قرار می دهد.

به عنوان مثال طبق کدی زیر، آرایه scores را در نظر بگیرید. حال قصد داریم امتیاز هایی که بالای 75 هستند را فیلتر کنیم.
در همچین حالتی طبق کد زیر عمل می کنیم:

let scores = [12, 90, 14, 72, 89, 51]

let filteredScores = scores.filter(function (score) {
    return score > 75
})

console.log(filteredScores) // [90, 89]

همان طور که مشاهده می کنید، داخل فانکشن ورودی متد filter آن دسته از score هایی که از 50 بیشتر باشند را return کرده ایم.
تک تک آیتم های آرایه scores به ترتیب وارد فانکشن شده و مورد بررسی قرار می گیرند و هر کدام از آن ها که در مقایسه با شرط مورد نظرمان true باشند، همان score برای ما return و فیلتر می شود و در نهایت داخل آرایه filteredScores به تمام آیتم های بزرگ تر از 50 آرایه scores دسترسی داریم.

برای درک بهتر به مثال زیر هم توجه کنید:

let fruits = [' ', ' ', ' ', ' ', ' ️', ' ']

let filteredData = fruits.filter(function (fruit) {
    return fruit === ' '
})

console.log(filteredData) // [' ']

همان طور که در کد بالا مشاهده می کنید، آرایه ای تحت عنوان fruits با آیتم های چند میوه ذخیره کردیم و در خط بعد قصد داریم میوه ای که اسمش برابر با است را فیلتر کرده و برداریم.

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

آموزش جاوا اسکریپت

استفاده از arrow function در ورودی متد ها

مبحث arrow function در Es6 ارائه شده است و به این دلیل که ممکن خیلی از دوستان با Es6 کار نکرده باشند، در قسمت های قبلی سعی کرده با فانکشن های معمولی کار کنیم، اما می توانید از توابع arrow نیز استفاده کنید.

به کد زیر توجه کنید:

let scores = [12, 90, 14, 72, 89, 51]

let filteredScores = scores.filter(score => { 
    return score > 75 
})

console.log(filteredScores) // [90, 89]


let scores = [12, 90, 14, 72, 89, 51]

let doubleScores = scores.map(score => { 
    return score * 2
})

console.log(doubleScores) // [24, 180, 28, 144, 178, 102]

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

دسترسی به index آیتم ها

همان طور که تا این قسمت متوجه شدید، متد های map و filter تابع مورد نظرمان را به ازای تک تک آیتم های آرایه تکرار می کنند. حال ممکن است در استفاده از متد های map و filter قصد داشته باشید در هر دفعه تکرار به ازای هر آیتم از آرایه، داخل فانکشن به ایندکس آن آیتم نیز دسترسی داشته باشید.

همان طور که توضیح داده شد، برای دسترسی به آیتم های آرایه یک ورودی با اسم دلخواه را به فانکشن ارسال می کنیم. حال اگر بخواهیم داخل فانکشن به ایندکس همان آیتم هم دسترسی داشته باشیم، باید یک ورودی دیگری هم به فانکشن ارسال کنیم. اسم این ورودی هم دلخواه است اما به خاطر خوانایی بالا عمدتا از کلمه index استفاده می شود.

به تکه کد زیر دقت کنید:

let scores = [12, 90]

scores.map(function (score, index) {
    console.log(score, index) // (12 0) - (90 1)
})

طبق کد بالا یک آرایه با دو آیتم با مقادیر 12 و 90 با ایندکس های 0 و 1 داریم و دفعه اول که متد map وارد فانکشن می شود، دو ورودی با اسامی score = 12 و index = 0 دارد. در دفعه بعد که به ازای آیتم بعدی تکرار می شود، داخل فانکشن به دو ورودی score = 90 و index = 1 دسترسی داریم.

در کل با این سینتکس می توانید در هر دفعه که فانکشن به ازای یک آیتم از آرایه اجرا می شود، به ایندکس همان آیتم نیز دسترسی داشته باشید.

آموزش جاوا اسکریپت

سخن پایانی

در این مقاله سعی کردیم به کاربرد متد های map و filter در جاوا اسکریپت بپردازیم. اگر در درک سینتکس و نحوه عملکرد متد های ذکر شده مشکلی داشتین، لطفا ویدئوی مربوط به این مقاله را مشاهده کرده و در صورت وجود هر گونه سوال و ابهام در قسمت کامنت های مطرح کنید تا پاسخ داده شود.

تا مقاله بعدی خدانگهدار.

نظرات
ثبت نظر جدید
morteza_mp | کاربر
1402/08/12

فرق بین foreach با متد map چیه میشه توضیح بدین؟

محمدامین سعیدی راد | مدرس
1402/08/16

سلام مرتضی جان.
هر دو یه loop روی آرایه اجرا می‌کنن و با هر دوش می‌تونیم به ازای آیتم های آرایه یه تسکی رو انجام بدیم.
متد forEach بهمون خروجی نمیده (خروجیش undefined هست) ولی متد map همیشه یه آرایه return می‌کنه.

آموزش جاوا اسکریپت