দ .reduce()
পদ্ধতিটি ES5 এও ছিল, কিন্তু আমি কখনই ব্যবহার করিনি বা কাউকে সেই সময়ে উৎপাদনে ব্যবহার করতে দেখিনি। আজও দেখি মানুষ এই পদ্ধতি সম্পর্কে সচেতন নয়। আমিও দেখেছি মানুষ শুধু একই দিতে shopping cart example
এই পদ্ধতিটি ব্যাখ্যা করার সময় এবং, তাই আমি মনে করি লোকেরা এটি সম্পূর্ণরূপে বুঝতে পারে না। আমি মনে করি এই কারণেই এই পদ্ধতিটি কম মূল্যায়ন করা হয়েছে যদিও এটি শক্তিশালী।
আমি যখন প্রথমবার এটির সম্মুখীন হলাম, আমি শপিং কার্ট গণনা করার জন্য নিয়মিত ফর লুপের সাথে খুশি ছিলাম। আমি এই ধরনের কাজের জন্য এটি ব্যবহার করতে চাই না. কিন্তু এই পদ্ধতিতে গভীরভাবে খনন করার পরে, আমি বুঝতে পেরেছি যে আমি আরও অনেক কিছু করতে পারি।
বিভিন্ন টুইট এবং ব্লগ পড়ার পর, আমি ঠিক করেছি যে হ্রাস করার পদ্ধতিটি ঠিক কী এবং এর কিছু ব্যবহারের ক্ষেত্রে কী হতে পারে সে সম্পর্কে একটি বিস্তারিত নিবন্ধ লেখার সিদ্ধান্ত নিয়েছি। আমরা রেগুলার ফর লুপ এবং .reduce() এর গতি নিয়ে কথা বলব না কারণ ফর লুপ অন্য যেকোন অ্যারে পদ্ধতির চেয়ে দ্রুত। reduce
, map
, filter
, sort
, forEach
ইত্যাদি
আপনার মনে কোনো বাস্তব-বিশ্ব ব্যবহারের ক্ষেত্রে থাকলে, আমাকে জানান। আমি এই নিবন্ধে সেই উদাহরণগুলি অ্যাট্রিবিউশন সহ যোগ করব।
.reduce() বোঝা
আমরা ব্যবহার করতে পারি .reduce()
একটি অ্যারেতে এবং এটি একটি রিডুসার ফাংশন চালায় (একটি কলব্যাক ফাংশন) প্রতিটি উপাদানে এবং, আমরা এই রিডুসার ফাংশনের যুক্তি সংজ্ঞায়িত করতে পারি। এই .reduce() একটি দ্বিতীয় যুক্তিও গ্রহণ করে: initialValue
.
arr.reduce((accumulator, currentElement, currentIndex, array) => {
// your logic goes here...
}, initialValue);
এই রিডুসার ফাংশন (কলব্যাক) 4 টি আর্গুমেন্ট নেয়:
accumulator
: এটি কলব্যাক ফাংশন দ্বারা প্রত্যাবর্তিত সমস্ত মান জমা করে। তার মানে, কলব্যাক ফাংশনের শেষে, আপনি যে মানই ফেরত দেন না কেন, এটি পরবর্তী পুনরাবৃত্তির জন্য সঞ্চয়কারীর মান হয়ে যায়। পাস করলেinitialValue
এটি প্রথম পুনরাবৃত্তির জন্য সঞ্চয়কারীর মান হয়ে যায়। অন্যথায়, এটি প্রথম পুনরাবৃত্তিতে অ্যারের প্রথম মান নেয়।currentElement
: এটি বর্তমান পুনরাবৃত্তিতে প্রসেস করা অ্যারের বর্তমান উপাদানটির মান ধরে রাখে। আমরা পাস না হলেinitialValue
এটি অ্যারের ২য় এলিমেন্ট দিয়ে শুরু হয় কারণ অ্যাকিউমুলেটর ১ম এলিমেন্ট নেয়।currentIndex
: এটি সূচক (অবস্থান) এরcurrentElement
অ্যারের মধ্যে যদি না থাকেinitialValue
এটি সূচক 1 দিয়ে শুরু হয়, কারণ এই ক্ষেত্রে বর্তমান এলিমেন্টের অবস্থান।array
: এটি মূল অ্যারে রয়েছে যার উপর আমরা হ্রাস পদ্ধতিটি কার্যকর করছি। আপনার কিছু ক্ষেত্রে এই অ্যারের প্রয়োজন হতে পারে যেখানে আপনি একটি ভিন্ন ফাইল থেকে কলব্যাক ফাংশন আমদানি করছেন এবং সেই ফাইলটিতে মূল অ্যারের কোনো রেফারেন্স/প্রসঙ্গ নেই।
দ্রষ্টব্য: যদি আমরা ফাংশনের শেষে কোনো মান ফেরত না দেই, পরবর্তী পুনরাবৃত্তিতে, সঞ্চয়কারীর মান হয়ে যায়
undefined
.
ডকুমেন্টেশন অনুযায়ী, প্রথম 2টি আর্গুমেন্ট (সঞ্চয়কারী এবং বর্তমান উপাদান) প্রয়োজন কিন্তু আমরা কোনো আর্গুমেন্ট পাস না করেই এই ফাংশনটি চালাতে পারি (যা অকেজো) অন্য সব আর্গুমেন্ট ঐচ্ছিক.
এটি বিস্তারিতভাবে বোঝার জন্য একটি সহজ উদাহরণ নেওয়া যাক
const array = (1, 2, 3, 4, 5);
const value = array.reduce((acc, curr, i, arr) => {
acc += curr;
// Here curr = arr(i);
return acc;
// If we don't return any value,
// The accumulator becomes undefined in the next iteration
}, 0);
console.log(value); // 15
এই উদাহরণে, আমরা প্রাথমিক মান পাস করেছি: 0
সঞ্চয়কারীর এই কারণেই প্রথম পুনরাবৃত্তিতে:
- সঞ্চয়কারীর মান হয়ে যায়
0
. - CurrentElement মান ধারণ করে
1
. (অ্যারের প্রথম উপাদান) - কারণ বর্তমান উপাদান প্রথম মান ধারণ করে, তার সূচক হয়ে যায়
0
.
যদি আমরা প্রাথমিক মানটি সরিয়ে ফেলি, সঞ্চয়কারী অ্যারের প্রথম উপাদানটি ধরে রাখবে: 1
বর্তমান উপাদানটি দ্বিতীয় উপাদানটি ধরে রাখবে: 2
এবং সূচক শুরু হবে থেকে 1
.
কিন্তু ES5 সম্পর্কে কি? কোন তীর ফাংশন নেই…
ES5-এ, আমরা ফ্যাট অ্যারো ফাংশনটি দিয়ে প্রতিস্থাপন করতে পারি function
কীওয়ার্ড এবং, অন্য সবকিছু একই থাকে।
array.reduce(function(acc, curr, i, arr) {
// Your Logic
}, initialValue);
এখন এর কিছু ব্যবহার-ক্ষেত্র দেখা যাক
এখানে, এই বিভাগে, আমরা কীভাবে এবং কোথায় ব্যবহার করতে পারি তা দেখব .reduce()
. এই বিভাগের উদ্দেশ্য সর্বোত্তম সমাধান প্রদান করা নয় বরং নতুন ব্যবহারের ক্ষেত্রে অন্বেষণ করা।
আপনি যদি মৃত্যুদন্ডের গতি সম্পর্কে উদ্বিগ্ন হন তবে ব্যবহার করবেন না reduce
, map
, forEach
ইত্যাদি for loop
.
.reduce() ব্যবহার করে .map() প্রতিলিপি করা
const array = (1, 2, 3, 4, 5);
const data = array.reduce((acc, curr) => {
// Your logic on `curr`
acc.push(curr);
return acc;
}, ());
console.log(data); // (1, 2, 3, 4, 5)
এই উদাহরণে, এর মান পাওয়ার পরে curr
আমরা এটিতে যেকোনো অপারেশন করতে পারি এবং সঞ্চয়কারীতে পুরানো/নতুন মান পুশ করতে পারি এবং ফেরত দিতে পারি।
.reduce() ব্যবহার করে .filter() এর প্রতিলিপি করা
এখন, আসুন সংখ্যার একটি অ্যারে ফিল্টার করার চেষ্টা করি এবং এর থেকে বড় সমস্ত সংখ্যা পেতে পারি 0
হ্রাস ব্যবহার করে।
const array = (-3, -2, -1, 0, 1, 2, 3);
const filtered = array.reduce((acc, curr) => {
if (curr > 0) {
acc.push(curr);
}
return acc;
}, ());
console.log(filtered); // (1, 2, 3)
অ্যারে থেকে ডুপ্লিকেট এন্ট্রি সরানো হচ্ছে
এটি ব্যবহার করে একটি অ্যারে থেকে ডুপ্লিকেট এন্ট্রি অপসারণ করা অত্যন্ত সহজ .reduce()
. এই পদ্ধতিটি ব্যবহার করার প্রধান সুবিধা হল এটি ES5 এর বিপরীতেও কাজ করবে Set
বা অন্য কিছু ES6+ নির্দিষ্ট উপায়।
const array = (1, 2, 1, 2, 3, 1, 4, 5, 4);
const unique = array.reduce((acc, curr) => {
if (acc.indexOf(curr) === -1) {
acc.push(curr);
}
return acc;
}, ());
console.log(unique); // (1, 2, 3, 4, 5)
একটি অ্যারে থেকে সমস্ত আইটেম সমতল করা
আমাদের যদি এমন একটি অ্যারে থাকে যাতে চলুন সংখ্যা এবং সংখ্যার অ্যারে থাকে এবং আমরা অ্যারে থেকে সমস্ত মান চাই, আমরা সহজেই একটি অ্যারেকে সমতল করতে পারি .reduce()
.
আমি কিছু API কল করার সময় এটির সম্মুখীন হয়েছি যে যদি শুধুমাত্র 1টি উপাদান থাকে তবে এটি একটি স্ট্রিং প্রদান করে। অন্যথায়, এটি স্ট্রিংগুলির একটি অ্যারে প্রদান করে।
const array = ((1, 2, 3), 4, 5, (6, 7));
const flatten = array.reduce((acc, curr) => {
if (Array.isArray(curr)) {
acc.push(...curr);
} else {
acc.push(curr)
}
return acc;
}, ());
console.log(flatten); // (1, 2, 3, 4, 5, 6, 7)
আমরা টারনারি অপারেটর ব্যবহার করে এই কলব্যাক ফাংশনটি 1 লাইনে লিখতে পারি, তবে বোঝার সুবিধার জন্য, আমি if/else শর্তটি রেখেছি।
একটি অ্যারেকে একটি অবজেক্টে রূপান্তর করা এবং ঘটনাগুলি গণনা করা
এটি একটি খুব সাধারণ ব্যবহারের ক্ষেত্রে, এবং বেশিরভাগ সময়, আমি দেখছি লোকেরা “” ব্যবহার করছেlodash” বা অনুরূপ লাইব্রেরিগুলি এই ধরনের ছোট কাজগুলি সম্পাদন করার জন্য৷ আমি আমার প্রোজেক্টকে অনেকগুলি লাইব্রেরি দিয়ে ফোলাতে পছন্দ করি না যা আমি সবেমাত্র একবার বা দুবার ব্যবহার করি এবং সহজেই ভ্যানিলা জেএস কোডের কয়েকটি লাইন দ্বারা প্রতিস্থাপিত হতে পারি৷
এটি আপনার অ্যারের প্রতিটি আইটেমের সংঘটনের সংখ্যা গণনা করার সবচেয়ে সহজ উদাহরণ হতে পারে:
const array = ('🍎', '🍌', '🍌', '🍎', '🍇', '🍌');
const obj = array.reduce((acc, curr) => {
if (acc(curr)) {
acc(curr) += 1;
} else {
acc(curr) = 1;
}
return acc;
}, {});
console.log(obj); // {🍎: 2, 🍌: 3, 🍇: 1}
.map() এর সাথে .reduce() চেইন করা
এটা কি সম্ভব যে আমরা সম্পর্কে কথা বলা .reduce()
এবং প্রত্যেকের প্রিয় উল্লেখ না shopping cart
উদাহরণ?
কিন্তু এখানে, এর নতুন কিছু চেষ্টা করা যাক. এখন এই সমস্ত উদাহরণ বোঝার পরে, সবাই জানে যে নীচের উদাহরণে আমরা পাস করতে পারি 0
অ্যাকিউমুলেটর এবং রিটার্নের প্রাথমিক মান হিসাবে acc + curr.price
.
কিন্তু আপনি কি জানেন, আপনি চেইন ম্যাপও কমাতে পারেন? আমি নিশ্চিত যে উদাহরণটি দেখার পরে, আপনি মনে করবেন যে এটি সুস্পষ্ট, তবে অন্তত আমরা নতুন কিছু চেষ্টা করেছি! এছাড়াও, এটি কর্মক্ষমতাকে আরও ক্ষয় করে। 🤷🏻
const items = (
{
item: '🍎',
price: 10,
},
{
item: '🍌',
price: 20,
},
{
item: '🍇',
price: 15,
},
);
const total = items
.map(item => item.price)
.reduce((acc, curr) => acc + curr);
console.log(total); // Output: 45
হ্যাশ ম্যাপে অবজেক্টের একটি অ্যারে রূপান্তর করা হচ্ছে
এক সেকেন্ড অপেক্ষা করুন, আমি নতুন ES6 বৈশিষ্ট্য সম্পর্কে কথা বলছি না: Map
. যদিও আমরা ব্যবহার করে একই জিনিস অর্জন করতে পারি Map
কিন্তু ব্যবহারের কিছু সুবিধা এবং অসুবিধা আছে Map
একটি উপর Object
.
এখন, ধরুন আপনার কাছে এই ধরনের বস্তুর একটি অ্যারে আছে:
const arr = (
{ key: 'Tom', value: 'Jerry' },
{ key: 'Mario', value: 'Luigi' },
{ key: 'SpongeBob', value: 'Patrick' },
);
এবং, আপনি এই মত একটি মূল জোড়া চান:
{
"Tom": "Jerry",
"Mario": "Luigi",
"SpongeBob": "Patrick",
}
আপনি সহজভাবে ব্যবহার করে এই অর্জন করতে পারেন .reduce()
নিচের উদাহরণের মত। এটা কি অত্যন্ত সহজ এবং সরল নয়?
const keyPair = arr.reduce((acc, curr) => {
acc(curr.key) = curr.value;
return acc;
}, {});
ঠিক আছে, এখন আমরা আলোচনা করেছি Map
চলুন সেখানে আলোচনা ছেড়ে না. আসুন দেখি কিভাবে আমরা ES6 এর মধ্যে একই জিনিস অর্জন করতে পারি: Map
. এখানে, আমরা কোনটি ভাল তা নিয়ে আলোচনা করছি না কারণ এটি ব্যবহারের ক্ষেত্রে নির্ভর করে। আমরা একটি পৃথক ব্লগে এই বিষয়ে আলোচনা করতে পারেন. কিন্তু আপাতত এই উদাহরণটি উপভোগ করা যাক।
এখানে, আমরা ব্যবহার করব .map()
একটি তৈরি করতে Map
!!!
const keyPair = new Map(arr.map(
item => (item.key, item.value)
));
console.log(keyPair); // {"Tom" => "Jerry", "Mario" => "Luigi", "SpongeBob" => "Patrick"}
উপসংহার
এই নিবন্ধে, আমাদের মূল ফোকাস ছিল বিভিন্ন ব্যবহারের ক্ষেত্রে বোঝা এবং অন্বেষণ করা .reduce()
. অবশ্যই, এটা নিয়মিত তুলনায় ধীর for loop
কিন্তু অপেক্ষাকৃত ছোট অবজেক্ট/অ্যারেগুলির জন্য, আপনি পার্থক্য অনুভব করবেন না (এটি প্রতিটি উপাদানের উপর আপনি যে কাজটি করছেন তার উপরও নির্ভর করে)।
একই কারণে, আপনি ব্যবহার করতে পারেন reduce
, map
, forEach
ইত্যাদি ফ্রন্টএন্ডে কারণ ব্রাউজারটিকে শুধুমাত্র 1 ক্লায়েন্টের জন্য এই কোডটি চালাতে হবে। কিন্তু আমি ব্যাকএন্ডে এটি সুপারিশ করব না কারণ সীমিত মেশিন রয়েছে এবং তাদের প্রচুর অনুরোধগুলি পরিচালনা করতে হবে। বাঁচাতে পারলেও 10 ms
একটি বৃহৎ বস্তুর জন্য, এটি একই সাথে অনেক অনুরোধ পরিচালনা করার সময় একটি বিশাল পার্থক্য করতে পারে। এই ধরনের ক্ষেত্রে, আপনি লুপ জন্য নিয়মিত জন্য যেতে হবে. এমনকি প্রতিটি কোণ থেকে আপনার কোডটি অপ্টিমাইজ করার পরেও আপনি মনে করেন যে কোডটি এখনও ধীর, এটি ভাষা পরিবর্তন করার সময়! (C/C++ হতে পারে!)
আমাকে জানাতে দিন টুইটার (এবং সম্ভব হলে অনুসরণ করুন 🙈) যদি আপনার মনে অন্য কোন ব্যবহার-কেস থাকে যা আপনি উত্পাদনে ব্যবহার করেন বা আপনি বাক্সের বাইরে কিছু ভেবে থাকতে পারেন। আমি তাদের সম্বোধন করতে এবং এই নিবন্ধে তাদের অন্তর্ভুক্ত করতে চাই।
ক্রেডিট
কভার ছবি: https://morioh.com/