۵۰ درصد تخفیف ویژه برای همه دوره‌ها از شنبه

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

در این مقاله، با نحوه عملکرد متد

filter()
filter()، کاربردهای عملی آن، تکنیک‌های پیشرفته و بهترین شیوه‌ها آشنا می‌شویم تا بتوانیم منطق فیلتر کردن داده‌ها را به‌شکلی مؤثر و بهینه پیاده‌سازی کنیم.

سینتکس و پارامترهای متد filter()

ساختار کلی استفاده از متد

filter()
filter() به این شکل است:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const newArray = originalArray.filter(callbackFunction(element,index, array),thisArg);
const newArray = originalArray.filter(callbackFunction(element,index, array),thisArg);
const newArray = originalArray.filter(callbackFunction(element,index, array),thisArg);

این متد پارامترهای زیر را دریافت می‌کند:

نکته: اگر هیچ المنتی شرایط مشخص شده را برآورده نکند، متد

filter()
filter() یک آرایه خالی return می‌کند.

نحوه عملکرد متد ()filter

برای درک بهتر فرآیند متد filter در جاوااسکریپت،مثال ساده‌ای را بررسی می‌کنیم که هم بدون استفاده از

filter()
filter() نوشته شده و هم با استفاده از آن.

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

filter()
filter()، معمولاً با استفاده از یک حلقه
for
for به شکل زیر عمل می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const words = ["apple", "banana", "kiwi", "pomegranate", "grape"];
const longwords = [];
for (let i = 0; i < words.length; i++) {
if (words[i].length > 5) {
longwords.push(words[i]);
}
}
console.log(longwords); //['banana', 'pomegranate']
const words = ["apple", "banana", "kiwi", "pomegranate", "grape"]; const longwords = []; for (let i = 0; i < words.length; i++) { if (words[i].length > 5) { longwords.push(words[i]); } } console.log(longwords); //['banana', 'pomegranate']
const words = ["apple", "banana", "kiwi", "pomegranate", "grape"];
const longwords = [];

for (let i = 0; i < words.length; i++) {
  if (words[i].length > 5) {
    longwords.push(words[i]);
  }
}

console.log(longwords); //['banana', 'pomegranate']

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

اکنون، همین منطق را با استفاده از متد

filter()
filter() ساده‌تر می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const words = ["apple", "banana", "kiwi", "pomegranate", "grape"];
const longwords = words.filter((word) => word.length > 5);
console.log(longwords); //['banana', 'pomegranate']
const words = ["apple", "banana", "kiwi", "pomegranate", "grape"]; const longwords = words.filter((word) => word.length > 5); console.log(longwords); //['banana', 'pomegranate']
const words = ["apple", "banana", "kiwi", "pomegranate", "grape"];
const longwords = words.filter((word) => word.length > 5);

console.log(longwords); //['banana', 'pomegranate']

متد

filter()
filter() خودش به‌صورت داخلی عمل «تکرار» را انجام می‌دهد و نیازی به استفاده از حلقه
for
for نیست. بر اساس نتیجه تابع callback، هر المنت به‌صورت خودکار به آرایه جدید اضافه می‌شود.

نکته: متد

filter()
filter() فقط روی آرایه‌ها کاربرد دارد. اگر بخواهیم آن را روی نوع‌های داده‌ای دیگر در جاوااسکریپت اعمال کنیم، ابتدا باید آن داده‌ها را به آرایه تبدیل نماییم.

موارد کاربرد عملی متد ()filter

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

فیلتر کردن ساده

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

برای این کار، می‌توانیم از یک arrow function برای تعریف شرط فیلتر به‌صورت مختصر استفاده کنیم.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const productPrices = [15.99, 25.50, 10.00, 30.75, 5.49, 22.00];
const expensiveProducts = productPrices.filter(price => price > 20);
console.log(expensiveProducts)
// Result: [25.5, 30.75, 22]
const productPrices = [15.99, 25.50, 10.00, 30.75, 5.49, 22.00]; const expensiveProducts = productPrices.filter(price => price > 20); console.log(expensiveProducts) // Result: [25.5, 30.75, 22]
const productPrices = [15.99, 25.50, 10.00, 30.75, 5.49, 22.00];
const expensiveProducts = productPrices.filter(price => price > 20);

console.log(expensiveProducts)
// Result: [25.5, 30.75, 22]

جست‌وجو در یک آرایه

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const names = ['John', 'Alice', 'Jonathan', 'Bob', 'Joanna'];
const searchQuery = 'jo';
const searchResults = names.filter(name =>
name.toLowerCase().includes(searchQuery.toLowerCase())
);
console.log(searchResults)
// Result: ['John', 'Jonathan', 'Joanna']
const names = ['John', 'Alice', 'Jonathan', 'Bob', 'Joanna']; const searchQuery = 'jo'; const searchResults = names.filter(name => name.toLowerCase().includes(searchQuery.toLowerCase()) ); console.log(searchResults) // Result: ['John', 'Jonathan', 'Joanna']
const names = ['John', 'Alice', 'Jonathan', 'Bob', 'Joanna'];
const searchQuery = 'jo';
const searchResults = names.filter(name => 
  name.toLowerCase().includes(searchQuery.toLowerCase())
);

console.log(searchResults)
// Result: ['John', 'Jonathan', 'Joanna']

فیلتر کردن آبجکت‌ها بر اساس ویژگی‌های مشخص

متد

filter()
filter() را می‌توانیم روی آرایه‌ای از آبجکت‌ها به کار ببریم تا المنت‌ها را بر اساس مقدار ویژگی خاصی فیلتر کنیم.

برای مثال، فرض کنید یک پلتفرم محتوایی داریم که هر پست به‌صورت یک آبجکت شامل ویژگی‌هایی مانند

id
id،
title
title و
tags
tags تعریف شده است. اگر بخواهیم فقط پست‌هایی را نمایش دهیم که دارای برچسب
"tech"
"tech" هستند، می‌توانیم از
filter()
filter() برای استخراج آن‌ها استفاده کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const posts = [
{ id: 1, title: 'AI Breakthrough', tags: ['tech', 'science']},
{ id: 2, title: 'Travel Guide', tags: ['lifestyle'] },
{ id: 3, title: 'New JavaScript Framework', tags: ['tech'] },
];
const techPosts = posts.filter(post => post.tags.includes('tech'))
console.log(techPosts)
// Result: [
// { id: 1, title: 'AI Breakthrough', tags: [ 'tech', 'science' ] },
// { id: 3, title: 'New JavaScript Framework', tags: [ 'tech' ] }
// ]
const posts = [ { id: 1, title: 'AI Breakthrough', tags: ['tech', 'science']}, { id: 2, title: 'Travel Guide', tags: ['lifestyle'] }, { id: 3, title: 'New JavaScript Framework', tags: ['tech'] }, ]; const techPosts = posts.filter(post => post.tags.includes('tech')) console.log(techPosts) // Result: [ // { id: 1, title: 'AI Breakthrough', tags: [ 'tech', 'science' ] }, // { id: 3, title: 'New JavaScript Framework', tags: [ 'tech' ] } // ]
const posts = [
  { id: 1, title: 'AI Breakthrough', tags: ['tech', 'science']},
  { id: 2, title: 'Travel Guide', tags: ['lifestyle'] },
  { id: 3, title: 'New JavaScript Framework', tags: ['tech'] },
];
const techPosts = posts.filter(post => post.tags.includes('tech'))

console.log(techPosts)
// Result: [
//   { id: 1, title: 'AI Breakthrough', tags: [ 'tech', 'science' ] },
//   { id: 3, title: 'New JavaScript Framework', tags: [ 'tech' ] }
// ]

فیلتر کردن داده‌های نامعتبر

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

filter()
filter() این کار را به‌صورت مؤثر انجام دهیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const rawData = ["Hello", "", 42, null, undefined, "JavaScript"];
const cleanData = rawData.filter(item => item !== null && item !== undefined && item !== '');
console.log(cleanData);
//Result: [ 'Hello', 42, 'JavaScript' ]
const rawData = ["Hello", "", 42, null, undefined, "JavaScript"]; const cleanData = rawData.filter(item => item !== null && item !== undefined && item !== ''); console.log(cleanData); //Result: [ 'Hello', 42, 'JavaScript' ]
const rawData = ["Hello", "", 42, null, undefined, "JavaScript"];
const cleanData = rawData.filter(item => item !== null && item !== undefined && item !== '');

console.log(cleanData);
//Result: [ 'Hello', 42, 'JavaScript' ]

یک روش ساده‌تر برای حذف مقادیر ناخواسته، استفاده از

Boolean
Boolean به‌عنوان تابع بازگشتی است. این روش تمام مقادیر falsy (مانند
null
null،
undefined
undefined،
false
false،
""
"" و
NaN
NaN) را حذف می‌کند:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const cleanData = rawData.filter(Boolean);
const cleanData = rawData.filter(Boolean);
const cleanData = rawData.filter(Boolean);

فیلتر کردن مقادیر تکراری

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

filter()
filter() و
indexOf()
indexOf() انجام دهیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const duplicates = [1, 2, 2, 3, 4, 4, 5];
const uniqueValues = duplicates.filter((item, index, arr) =>
arr.indexOf(item) === index
//Compares the first occurrence index with the current index
);
console.log(uniqueValues)
// Result: [1, 2, 3, 4, 5]
const duplicates = [1, 2, 2, 3, 4, 4, 5]; const uniqueValues = duplicates.filter((item, index, arr) => arr.indexOf(item) === index //Compares the first occurrence index with the current index ); console.log(uniqueValues) // Result: [1, 2, 3, 4, 5]
const duplicates = [1, 2, 2, 3, 4, 4, 5];
const uniqueValues = duplicates.filter((item, index, arr) => 
  arr.indexOf(item) === index
//Compares the first occurrence index with the current index
);

console.log(uniqueValues)
// Result: [1, 2, 3, 4, 5]

متد

indexOf(item)
indexOf(item) اولین ایندکس المنت مورد نظر را در آرایه پیدا می‌کند. با مقایسه این ایندکس با ایندکس فعلی، فقط اولین تکرار از هر المنت در آرایه باقی می‌ماند.

این روش برای آرایه‌هایی با مقادیر اولیه (مانند اعداد و رشته‌ها) به‌خوبی عمل می‌کند، اما برای آبجکت‌ها کاربرد ندارد، زیرا هر آبجکت، مرجعی یکتا دارد و مقایسه‌ آن‌ها از نظر ارجاعی صورت می‌گیرد.

تکنیک‌های پیشرفته: زنجیره‌سازی متد ()filter با سایر متدهای آرایه‌ای

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

map()
map() و
reduce()
reduce() ترکیب نماییم. این فرآیند که با عنوان زنجیره‌سازی (chaining) شناخته می‌شود، به توسعه‌دهندگان این امکان را می‌دهد که چندین متد را به‌صورت متوالی و در یک جریان یکپارچه اجرا کنند.

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

پیش از بررسی chaining، مروری کوتاه بر عملکرد متدهای مورد استفاده خواهیم داشت:

در ادامه، نحوه ترکیب این متدها در سناریوهای کاربردی مورد بررسی قرار می‌دهیم.

زنجیره‌سازی ()filter با ()map

یکی از رایج‌ترین کاربردهای ترکیب

filter()
filter() و
map()
map()، پالایش داده‌های دریافتی از API است. اغلب، پاسخ‌های دریافتی از سمت سرور حاوی مقادیر ناقص یا نامعتبر هستند. در چنین مواردی، با استفاده از زنجیره‌سازی این دو متد می‌توانیم ابتدا داده‌های نامطلوب را حذف و سپس مقادیر باقی‌مانده را به فرمتی استاندارد تبدیل نماییم.

به‌عنوان مثال، در یک سامانه مدیریت محتوا، ممکن است لیستی از مقالات از طریق API دریافت شود که برخی از آن‌ها فاقد عنوان یا در وضعیت «پیش‌نویس» باشند. برای نمایش تنها مقالات منتشرشده با عنوان معتبر، می‌توانیم از قطعه کد زیر استفاده کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const dummyData = [
{ id: 1, title: ' JavaScript Guide ', status: 'DRAFT' },
{ id: 2, title: 'React Basics', status: 'PUBLISHED' },
{ id: 3, title: ' ', status: 'PUBLISHED' }, // Invalid title
];
const publishedArticles = dummyData
.filter(item => item.title.trim() !== '' && item.status === 'PUBLISHED')
// Remove empty titles and drafts
.map(item => ({
...item, // Copy all values from the original array
title: item.title.trim().toLowerCase(), // Normalize title
}));
console.log(publishedArticles);
// Result: [{ id: 2, title: 'react basics', status: 'PUBLISHED' }]
const dummyData = [ { id: 1, title: ' JavaScript Guide ', status: 'DRAFT' }, { id: 2, title: 'React Basics', status: 'PUBLISHED' }, { id: 3, title: ' ', status: 'PUBLISHED' }, // Invalid title ]; const publishedArticles = dummyData .filter(item => item.title.trim() !== '' && item.status === 'PUBLISHED') // Remove empty titles and drafts .map(item => ({ ...item, // Copy all values from the original array title: item.title.trim().toLowerCase(), // Normalize title })); console.log(publishedArticles); // Result: [{ id: 2, title: 'react basics', status: 'PUBLISHED' }]
const dummyData = [
  { id: 1, title: '  JavaScript Guide  ', status: 'DRAFT' },
  { id: 2, title: 'React Basics', status: 'PUBLISHED' },
  { id: 3, title: '  ', status: 'PUBLISHED' }, // Invalid title
];

const publishedArticles = dummyData
  .filter(item => item.title.trim() !== '' && item.status === 'PUBLISHED') 
// Remove empty titles and drafts
  .map(item => ({
    ...item, // Copy all values from the original array
    title: item.title.trim().toLowerCase(), // Normalize title
  }));

console.log(publishedArticles);
// Result: [{ id: 2, title: 'react basics', status: 'PUBLISHED' }]

زنجیره‌سازی ()filter با ()reduce

ترکیب متدهای

filter()
filter() و
reduce()
reduce() در مواقعی مفید است که لازم است ابتدا المنت‌های خاصی از آرایه انتخاب کزده و سپس یک مقدار نهایی از آن‌ها محاسبه نماییم.

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const products = [
{ name: 'Laptop', price: 1000, inStock: true },
{ name: 'Phone', price: 500, inStock: false },
{ name: 'Tablet', price: 750, inStock: true },
]
const totalStockValue = products
.filter((product) => product.inStock) // Keep only in-stock products
.reduce((sum, product) => sum + product.price, 0) // Add up prices
console.log(totalStockValue)
// Result: 1750
const products = [ { name: 'Laptop', price: 1000, inStock: true }, { name: 'Phone', price: 500, inStock: false }, { name: 'Tablet', price: 750, inStock: true }, ] const totalStockValue = products .filter((product) => product.inStock) // Keep only in-stock products .reduce((sum, product) => sum + product.price, 0) // Add up prices console.log(totalStockValue) // Result: 1750
const products = [
  { name: 'Laptop', price: 1000, inStock: true },
  { name: 'Phone', price: 500, inStock: false },
  { name: 'Tablet', price: 750, inStock: true },
]

const totalStockValue = products
  .filter((product) => product.inStock) // Keep only in-stock products
  .reduce((sum, product) => sum + product.price, 0) // Add up prices

console.log(totalStockValue)
// Result: 1750

با chaining متدهای آرایه‌ای در جاوااسکریپت، می‌توانیم عملیات پیچیده را با وضوح بالا و به‌صورت مؤثر انجام دهیم، بدون آنکه خوانایی یا نگه‌داری کد تحت‌تأثیر قرار گیرد.

بهترین شیوه‌ها برای نوشتن منطق فیلتر کردن مؤثر

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

تابع callback را بهینه بنویسیم

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

از arrow functionها استفاده کنیم

arrow functionها باعث کوتاه‌تر شدن کد، افزایش خوانایی و حذف کدهای تکراری می‌شوند. این موضوع در بهبود ساختار کلی پروژه نیز مؤثر خواهد بود.

زنجیره‌های پیچیده را به بخش‌های کوچک‌تر تقسیم کنیم

زنجیره‌سازی متدهایی مانند

filter()
filter()،
map()
map() و
reduce()
reduce() روش مناسبی برای حذف متغیرهای میانی و حفظ انسجام کد است. با این حال، اگر زنجیره بیش از حد پیچیده شود، خوانایی آن کاهش می‌یابد. در چنین مواردی، پیشنهاد می‌شود بخش‌های مختلف زنجیره را به توابع مجزا با نام‌های گویا تقسیم کنیم تا درک و نگه‌داری کد آسان‌تر شود.

از تغییر ندادن داده‌های اولیه اطمینان حاصل کنیم

هنگام اعمال تغییر بر روی آبجکت‌ها، باید مراقب باشیم که داده‌های اولیه به‌صورت ناخواسته دچار تغییر (mutation) نشوند. استفاده از عملگر spread (

...
...)  راهکاری مطمئن برای ساخت نسخه‌های جدید از آبجکت‌ها است، بدون آنکه آبجکت اصلی دستخوش تغییر گردد.

پیامدهای عملکردی را در نظر بگیریم

در مواقعی که با مجموعه‌داده‌های بسیار بزرگ سروکار داریم، ممکن است استفاده از حلقه‌های

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

جمع‌بندی

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

map()
map() و
reduce()
reduce()، تلاش کردیم تصویری کامل از این ابزار قدرتمند ارائه دهیم.

با درک عمیق عملکرد این متد و رعایت نکات و شیوه‌های پیشنهادی، می‌توانیم کدی بنویسیم که هم تمیزتر و خواناتر باشد و هم از نظر عملکردی بهینه‌تر عمل کند.