# হাইয়ার অর্ডার ফাংশন (Higher Order Function)

শুরুতেই বিষয়টাকে একটু সহজ করার চেষ্টা করি। কারণ এই বিষয়টা সহজ হলেও বুঝতে গিয়ে অনেকেই গোলমাল পাকিয়ে ফেলে। ধরে নিন আপনি কোন ব্যাক্তিকে কখন হাইয়ার ক্লাসের লোক লোক বলবেন? যখন সে অনেক দায়িত্ব বা অনেক ডিপার্টমেন্ট সামলাচ্ছে। বিষয়টা আরো একটু ভাল করে বুঝার করার জন্য আমি ধরে নিতে পারি আপনার অফিসের CEO সাহেবকে। প্রশ্ন করুন নিজেকে কেন তিনি CEO ? দেখবেন তিনি হচ্ছেন এমন একজন ব্যাক্তি যে, অনেক লোকজনকে দিয়ে কাজ করাচ্ছেন এবং বিভিন্ন নিয়ম নিতি মেনে কোম্পানির সাফল্যে কাজ করে যাচ্ছেন। এক কথায় বলতে পারেন, অফিসে হাইয়ার লেভেল কাজ কর্ম গুলো তার দ্বারা বাস্তবায়িত হচ্ছে কোন না কোন ভাবে। হয় নিজের অফিসের লোকজন কে দিয়ে করিয়ে নিচ্ছেন না হয় বাইরের কাউকে দিয়ে। দিন শেষে তিনি প্রয়োজনীয় কাজ গুলো করিয়ে নিচ্ছেন।

**সংজ্ঞাঃ-**  হাইয়ার অর্ডার ফাংশন এমন একটা ফাংশন যেখানে আমরা  আরেকটা ফাংশনকে প্যারামিটার হিসেবে পাস করব। অথবা এর ভিতরে এক বা একাধিক ফাংশন লিখে আমাদের চাহিদা মতো কাজ করিয়ে নিব। টিক আমাদের অফিসের CEO সাহেবের মতো। &#x20;

এখন আমরা এমন একটা প্রোগ্রাম লিখব যেখানে আমাদের কিছু অ্যারে উপাদান থাকবে এবং আমরা ঐ অ্যারে এর প্রত্যেকটা উপাদানকে <mark style="color:blue;">`2`</mark> দ্বারা গুন করে আরেকটা নতুন অ্যারে বানাব। চলুন দেখে নেই।&#x20;

{% code title="multiply-array-el-by-2.js" overflow="wrap" lineNumbers="true" %}
```javascript
let elements = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let new_array = [];
for ( let element of elements ) {
    new_array.push( element * 2 );
  }
  
console.log(new_array)
```
{% endcode %}

#### Output:

```
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
```

এখন আসুন আমরা আসলে এই প্রোগ্রামটা নিয়ে একটু চিন্তা করি। কেন? কিভাবে? কি হচ্ছে ?&#x20;

> প্রথমে আমরা একটা `elements` নামে অ্যারে নিয়েছি টিক ১ নম্বার লাইনের মতো করে। এবং `new_array` নামে আরেকটা empty অ্যারে নিয়েছি টিক ২ নাম্বার লাইনের মতো করে। পরে for loop ব্যাবহার করে প্রতিটা element কে <mark style="color:blue;">`2`</mark> দিয়ে গুন করার পর `new_array` অ্যারেতে পুশ করে দিয়েছি। টিক যেমন টা দেখতে পাচ্ছেন ৩ থেকে ৫ নাম্বার লাইনের কোড গুলো। এবং সবশেষে কনসোল করে প্রিন্ট করা হয়েছে টিক যেমনটা দেখতে পাচ্ছেন ৭ নাম্বার লাইনে।&#x20;

এবার আসি আমরা এই যে কোড টা লিখলাম এতে আমাদের কাজ হচ্ছে কিন্তু কেউ যখন আমাদের বলবে ভাই <mark style="color:blue;">2</mark> এর পরিবর্তে এবার <mark style="color:blue;">3</mark> দিয়ে করে দেখান। অথবা আরেকজন বলল ভাই আমি গুন করব না আমি ভাগ করব। এমন আরো অনেক বিষয় বা সমস্যা তৈরি হতেই পারে একেক জন একেক ভাবে তাদের চিন্তার ভাব যুক্ত করতেই পারে কেমন হতো? যদি আমরা বিষয়টা কে একটু ডাইনামিক ভাবে করে দিতে পারি। যাতে করে যে যেমন লজিক লিখতে চাই সে শুধু ততটুকুই লিখবে। আসুন দেখে নেই।

{% code overflow="wrap" lineNumbers="true" %}
```javascript
function map( array, myDynamicFunction ) {
  let mapped = [];
  for ( let element of array ) {
    mapped.push(myDynamicFunction(element));
  }
  return mapped;
}

//multiply by 2
function multiply( element ){
  return element * 2;
}

//divide by 2
function divide( element ){
  return element / 2;
}

let elements = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

const results_of_multiplication = map(elements,multiply);
 
const results_of_division =  map(elements,divide);
```
{% endcode %}

> আসুন কোডটা একটু বুঝে নেই কি হচ্ছে? প্রথমে আমি একটা ফাংশন লিখে নিয়েছি <mark style="color:purple;">map</mark> নামে। যেমন টা দেখতে পাচ্ছেন **১-৭** নাম্বার লাইনের মত করে। যে ফাংশনটা প্যারামিটার হিসেবে দুইটা প্যারামিটার নেয়। প্রথমটা হচ্ছে `array`  দ্বিতীয়টা হচ্ছে আমাদের দেওয়া ডাইনামিক ফাংশন যেইটাকে আমি আসলে `myDynamicFunction` নামে লিখেছি। এবং পরে map  ফাংশন টা আমাদের `myDynamicFunction`  কল করার পর যা রিটার্ন করছে সেইটা আমাদের `mapped`  অ্যারে তে পুশ করে দিচ্ছে টিক লাইন নাম্বার **৪** এর মতো করে। এর পরে আমি আরও দুইটা ফাংশন লিখেছি <mark style="color:blue;">`multiply`</mark> নামে লাইন নাম্বার **১০ - ১২** এবং <mark style="color:blue;">`divide`</mark> নামে লাইন নাম্বার **১৪ - ১৭**। <mark style="color:blue;">`multiply`</mark> ফাংশনটা একটা প্যারামিটার নিচ্ছে এবং দুই দিয়ে গুন করছে। আর  <mark style="color:blue;">`divide`</mark> ফাংশনটাও একটা প্যারামিটার নিচ্ছে এবং পরে সেইটা কে দুই দিয়ে ভাগ করছে। পরে আমরা ১৯ নাম্বার লাইনের মতো করে একটা অ্যারে নিয়েছি যার নাম দিয়েছি `elements` এবং সেখানে আমরা কিছু সংখ্যা রেখেছি। এর পরে ২১ নাম্বার লাইনের মতো করে আমি map ফাংশন টা কল করে নিয়েছি এবং সেইটাতে আমাদের elements  অ্যারে এবং multiply ফাংশনটা পাস করে দিয়েছি এবং যে রেজাল্টটা পাচ্ছি সেইটা `results_of_multiplication` নামে একটা ভেরিয়েবলে রেখে দিচ্ছি। একই কাজ টা আমি লাইন নাম্বার ২৩ এ করেছি শুধু `multiply` এর পরিবর্তে `divide` লিখেছি এবং রেজাল্ট যেইটা পেয়েছি সেইটা `results_of_division` ভেরিয়েবলে রেখে দিয়েছি।&#x20;

একবার ভালো করে দেখুন তো আগের কোডে আপনি শুধু মাত্র এক ধরনের কাজ করতে পারতেন। আর এখন আপনি আপনার ইচ্ছা মতো কাজ করতে পারছেন। বিষয়টা সত্যিই মজার তাই না! তাছাড়া আগের কোডের দিকে লক্ষ্য করলে দেখবেন আপনার প্রতিটা লাইন দেখার পর বলতে পারতেন এই কোডটা আসলে কি করবে?  কিন্তু আমরা পরে যে কোড লিখেছি সেইটা ডাইনামিক অপারেশনের সাথে সাথে বোধগম্য কোডও দিচ্ছে। যেটা আসলেই অনেক ইফেক্টিভ অন্য প্রোগ্রামারদের জন্য যখন একসাথে কাজ করবেন।&#x20;

এমন অনেক কাজেই আছে যেগুলো আপনি নিমিষেই এমন ফাংশন লিখে করে ফেলতে পারেন আর রি-ইউজেবল করতে পারেন।&#x20;

#### কিছু প্রশ্নের উত্তর আপনার জানতে ইচ্ছা হবে এখন সেগুলো আমি উত্তর সহ নিচে বলে দিলাম

**১। হাইয়ার অর্ডার ফাংশন কি সবসময় কিছু রিটার্ন করবে?**

**উত্তরঃ** না! হাইয়ার অর্ডার ফাংশন আপনাকে রিটার্ন করবে কি করবে না সেইটা আপনার কাজের উপর নির্ভর করবে। কারণ সবসময় কিছু রিটার্ন চাইবেন এমন কাজ নাও করতে পারেন।

**২। জাভাস্কিপ্টে কি Built-in হায়ার অর্ডার ফাংশন আছে?**

**উত্তরঃ** হ্যাঁ। জাভাস্ক্রিপ্টে অনেক গুলো হায়ার অর্ডার ফাংশন আছে জেমনঃ map, filter, find, forEach ইত্যাদি

**৩। বিল্ড ইন এবং কাস্টম হায়ার ওর্ডার ফাংশনের কি কোন limitation আছে?**

**উত্তরঃ** হ্যাঁ ! আপনি যখন কোন Asynchronous টাস্ক করতে যাবেন আশা অনুরূপ রেজাল্ট নাও পেতে পারেন। তাছাড়া আপনি যে কাস্টম ফাংশনটা লিখেছেন অবস্যই একটা কমন প্যাটার্ন এ লিখতে হবে না হয় আশা অনুরূপ ফলাফল নাও পেতে পারেন।&#x20;

**৪। হায়ার অর্ডার ফাংশনের টাইম কমপ্লেক্সিটি কত?**

**উত্তরঃ** বুদ্ধিমানের উত্তর হচ্ছে আপনি যেমন কোড লিখবেন টাইম কমপ্লেক্সিটি ও তেমন হবে। তবে প্রশ্নটা যদি এমন হয় যে জাভাস্ক্রিপ্টে built-in ফাংশন গুলোর কমপ্লেক্সিটি নিয়ে তাহলে উত্তর হচ্ছে O(n)।
