Lesson ৮ মিনিট পড়া

অ্যারের হাইয়ার-অর্ডার মেথড (Array Higher-Order Methods)

লুপ ছাড়াই ডেটা উইজার্ডের মতো অ্যারেকে পরিবর্তন করুন বা ট্রান্সফর্ম, ফিল্টার এবং হিসাব-নিকাশ করুন

হাইয়ার-অর্ডার মেথড কেন প্রয়োজন? (Why Higher-Order Methods?)

কল্পনা করুন আপনার কাছে ১০০টি লেগো ইটের একটি বাক্স আছে। আপনি চান: সেখান থেকে শুধু লাল রঙের ইটগুলো বেছে নিতে, প্রতিটি ইটকে আগের চেয়ে দ্বিগুণ উঁচু করতে এবং সবশেষে মোট উচ্চতা মাপতে। আপনি চাইলে তিনটি আলাদা for লুপ লিখতে পারেন... বা আপনি হাইয়ার-অর্ডার অ্যারে মেথড (higher-order array methods) ব্যবহার করতে পারেন, যা এই পুরো কাজটিকে একটি পরিচ্ছন্ন ও সহজে পাঠযোগ্য চেইনের মাধ্যমে করে ফেলবে।

এই মেথডগুলো একটি কলব্যাক ফাংশন (callback function)-কে আর্গুমেন্ট হিসেবে গ্রহণ করে — এটি এমন একটি ছোট ফাংশন যা বর্ণনা করে প্রতিটি আইটেমের সাথে কী করতে হবে। মেথডটি স্বয়ংক্রিয়ভাবেই আপনার জন্য লুপ করার কাজটি করে দেয়। আপনার প্রতিনিয়ত যে তিনটি বড় মেথড প্রয়োজন হবে:

  • .map() — প্রতিটি আইটেমের পরিবর্তন বা ট্রান্সফর্ম করে → ফলাফলের একটি নতুন অ্যারে পান
  • .filter() — মাত্র সেই আইটেমগুলোকেই রাখে যেগুলো শর্ত পূরণ করে → একটি ছোট অ্যারে পান
  • .reduce() — সবগুলো আইটেমকে একটিমাত্র ভ্যালুতে পরিণত করে

Map, Filter এবং Reduce — সবচেয়ে বড় তিনটি অংশ (Map, Filter & Reduce — The Big Three)

let prices = [10, 25, 50, 75, 100];
// .map() — transform each item
let withTax = prices.map(price => price * 1.1);
console.log(withTax); // [11, 27.5, 55, 82.5, 110]
// .filter() — keep items that pass a test
let affordable = prices.filter(price => price <= 50);
console.log(affordable); // [10, 25, 50]
// .reduce() — combine into one value
let total = prices.reduce((sum, price) => sum + price, 0);
console.log(total); // 260
// 🔥 Chain them together!
let affordableTotal = prices
.filter(price => price <= 50) // [10, 25, 50]
.map(price => price * 1.1) // [11, 27.5, 55]
.reduce((sum, p) => sum + p, 0); // 93.5
console.log(affordableTotal); // 93.5
Output
[11, 27.5, 55, 82.5, 110]
[10, 25, 50]
260
93.5

খুঁজে বের করা — find, findIndex, some, every (Finding Things — find, findIndex, some, every)

মাঝেমধ্যেই আপনি পুরো একটি অ্যারেকে ট্রান্সফর্ম বা ফিল্টার করতে চান না — আপনি হয়তো কেবল নির্দিষ্ট কিছু একটা খুঁজে পেতে বা অ্যারে সম্পর্কে কোনো প্রশ্ন জিজ্ঞাসা করতে চান।

  • .find(fn)প্রথম যে আইটেমটি শর্ত বা টেস্টে উত্তীর্ণ হয়, তাকে রিটার্ন করে (অথবা undefined)
  • .findIndex(fn) — প্রথম ম্যাচ বা মিল পাওয়া আইটেমটির ইনডেক্স (index) রিটার্ন করে (অথবা -1)
  • .some(fn) — যদি অন্তত একটি আইটেমও পাস বা শর্ত পূরণ করে, তবে true রিটার্ন করে
  • .every(fn) — যদি সবগুলো আইটেম পাস বা শর্ত পূরণ করে, তবে true রিটার্ন করে
  • .includes(value) — কোনো নির্দিষ্ট ভ্যালু বা মান আছে কি না তা চেক করে (এটিতে কোনো কলব্যাক লাগে না)

Find, Some এবং Every

let users = [
{ name: "Anika", age: 28 },
{ name: "Rafi", age: 17 },
{ name: "Sadia", age: 35 },
{ name: "Tariq", age: 15 }
];
// .find() — first match
let firstAdult = users.find(u => u.age >= 18);
console.log(firstAdult); // { name: "Anika", age: 28 }
// .findIndex() — index of first match
let idx = users.findIndex(u => u.name === "Sadia");
console.log(idx); // 2
// .some() — is at least one person under 18?
console.log(users.some(u => u.age < 18)); // true
// .every() — is everyone over 18?
console.log(users.every(u => u.age >= 18)); // false
// .includes() — simple value check (no callback)
let nums = [1, 2, 3, 4, 5];
console.log(nums.includes(3)); // true
console.log(nums.includes(9)); // false
Output
{ name: "Anika", age: 28 }
2
true
false
true
false

Sort এবং forEach (Sort & forEach)

.sort() একটি অ্যারেকে সরাসরি বা ইন-প্লেস (in place) সাজিয়ে দেয় (এটি আসল অ্যারেকেই বদলে ফেলে!)। বাই-ডিফল্ট বা স্বয়ংক্রিয়ভাবে, এটি সবকিছুকে স্ট্রিংয়ে পরিণত করে এবং বর্ণানুক্রমিকভাবে সাজায় — যার মানে হলো [10, 2, 1] সাজানো হলে সেটি হয়ে যায় [1, 10, 2]! নম্বর বা সংখ্যাগুলোকে সঠিকভাবে সাজানোর জন্য আপনার একটি কম্পেয়ার ফাংশন (compare function) প্রয়োজন হবে।

.forEach() প্রতিটি আইটেমের জন্য একটি ফাংশন চালনা করে, কিন্তু কিছুই রিটার্ন করে না। এটি অনেকটা for...of লুপের মেথড ভার্সন। এটি তখনই ব্যবহার করবেন যখন আপনার একটি নতুন অ্যারে রিটার্ন করার বদলে কিছু সাইড-ইফেক্টের প্রয়োজন হবে (যেমন ফলাফলটি কনসোলে লগ করা)।

Sort এবং forEach

// .sort() — default is alphabetical (even for numbers!)
let nums = [30, 1, 100, 5, 20];
nums.sort();
console.log(nums); // [1, 100, 20, 30, 5] — WRONG for numbers!
// Sort numbers correctly with a compare function
nums.sort((a, b) => a - b); // ascending
console.log(nums); // [1, 5, 20, 30, 100]
nums.sort((a, b) => b - a); // descending
console.log(nums); // [100, 30, 20, 5, 1]
// Sort objects by a property
let students = [
{ name: "Zara", grade: 92 },
{ name: "Asif", grade: 88 },
{ name: "Mita", grade: 95 }
];
students.sort((a, b) => b.grade - a.grade);
console.log(students.map(s => `${s.name}: ${s.grade}`));
// .forEach() — do something for each item (no return value)
["আম", "জাম", "কাঁঠাল"].forEach((fruit, i) => {
console.log(`${i + 1}. ${fruit}`);
});
Output
[1, 100, 20, 30, 5]
[1, 5, 20, 30, 100]
[100, 30, 20, 5, 1]
["Mita: 95", "Zara: 92", "Asif: 88"]
1. আম
2. জাম
3. কাঁঠাল
Note: সহজে মনে রাখার চিট শিট (cheat sheet): একটি নতুন অ্যারে লাগবে? .map() ব্যবহার করুন। কম উপাদান বা আইটেম লাগবে? .filter() ব্যবহার করুন। একটিমাত্র ফলাফল লাগবে? .reduce() ব্যবহার করুন। নির্দিষ্ট কিছু খুঁজে বের করতে হবে? .find() ব্যবহার করুন। হ্যাঁ/না জাতীয় কোনো উত্তর লাগবে? .some() বা .every() ব্যবহার করুন। শুধু কোনো কাজ করতে চান? .forEach() ব্যবহার করুন। আপনার যদি break বা continue এর প্রয়োজন না পড়ে, তবে অযথাই for লুপ ব্যবহার করবেন না!
চ্যালেঞ্জ

ছোট কুইজ

[1, 2, 3].map(x => x * 2) কী রিটার্ন করবে?

পড়া চালিয়ে যান

FunctionsDOM Manipulation