লুপিং এবং ইটারেশন (Looping and Iteration in Clojure)
ক্লোজারে (Clojure) ইমিউটেবল ডেটা কাঠামোর উপর ভিত্তি করে লুপিং ও ইটারেশন করা হয়। সাধারণ প্রোগ্রামিং ভাষাগুলির মতো for বা while লুপ না থাকলেও, ক্লোজারে loop, recur, এবং উচ্চ স্তরের ফাংশন যেমন map, reduce, এবং filter এর মাধ্যমে ইটারেশন করা যায়। এখানে ক্লোজারের লুপিং এবং ইটারেশন নিয়ে আলোচনা করা হলো।
১. loop এবং recur (Loop and Recur)
ক্লোজারে loop এবং recur একসঙ্গে ব্যবহার করে রিকার্সন-ভিত্তিক লুপ তৈরি করা যায়। loop দিয়ে লুপ শুরু করা হয় এবং recur ব্যবহার করে পুনরাবৃত্তি করা হয়। recur প্রতি পুনরাবৃত্তিতে নতুন মান নিয়ে লুপ চালিয়ে যায়।
(loop [i 5]
(when (pos? i)
(println i)
(recur (dec i))))
; আউটপুট: ৫ ৪ ৩ ২ ১এখানে, i এর মান 5 থেকে শুরু করে প্রতি পুনরাবৃত্তিতে কমিয়ে 1 পর্যন্ত প্রিন্ট করা হয়।
ফ্যাক্টরিয়াল হিসাব করা:
(defn factorial [n]
(loop [i n result 1]
(if (zero? i)
result
(recur (dec i) (* result i)))))
(factorial 5) ; আউটপুট: ১২০এই উদাহরণে, factorial ফাংশন n এর ফ্যাক্টরিয়াল গণনা করতে loop এবং recur ব্যবহার করছে।
২. for লুপ (For Loop)
ক্লোজারে for মূলত লুপের মতো কাজ করে, তবে এটি লিস্ট কম্প্রিহেনশন হিসেবে পরিচিত। এটি একটি সিকোয়েন্সের প্রতিটি এলিমেন্টের উপর ইটারেট করে এবং একটি নতুন লিস্ট তৈরি করে।
(for [i (range 5)]
(* i i))
; আউটপুট: (০ ১ ৪ ৯ ১৬)এখানে for লুপটি ০ থেকে ৪ পর্যন্ত প্রতিটি সংখ্যার বর্গফল গণনা করে এবং একটি নতুন লিস্ট তৈরি করে।
৩. doseq লুপ (doseq Loop)
doseq ক্লোজারে সিকোয়েন্সের প্রতিটি এলিমেন্টের উপর ইটারেট করে এবং ইফেক্ট (পার্শ্বপ্রভাব) সম্পাদন করে, কিন্তু কিছু ফেরত দেয় না।
(doseq [i [1 2 3 4 5]]
(println i))
; আউটপুট: ১ ২ ৩ ৪ ৫এখানে, doseq প্রতিটি মান প্রিন্ট করছে এবং কোনো ফলাফল ফেরত দিচ্ছে না।
৪. map, reduce, এবং filter (High-Level Functions)
ক্লোজারে map, reduce, এবং filter উচ্চ-স্তরের ফাংশন যা সিকোয়েন্সের প্রতিটি এলিমেন্টের উপর কার্যকর হয়।
map
map ফাংশনটি একটি ফাংশন এবং একটি সিকোয়েন্স নেয় এবং প্রতিটি মানে ফাংশনটি প্রয়োগ করে একটি নতুন সিকোয়েন্স প্রদান করে।
(map #(* % %) [1 2 3 4])
; আউটপুট: (1 4 9 16)এখানে, map প্রতিটি সংখ্যার বর্গফল প্রদান করছে।
reduce
reduce ফাংশনটি একটি সিকোয়েন্সের উপর ইটারেট করে একটি একক ফলাফল প্রদান করে। এটি প্রথমে দুটি মান নিয়ে ফাংশন প্রয়োগ করে এবং তারপরে ফলাফলটির উপর পরবর্তী মান প্রয়োগ করে।
(reduce + [1 2 3 4 5])
; আউটপুট: ১৫এখানে, reduce প্রতিটি সংখ্যার যোগফল প্রদান করছে।
filter
filter ফাংশনটি একটি শর্ত এবং সিকোয়েন্স নেয় এবং শর্ত অনুযায়ী মানগুলো নির্বাচন করে একটি নতুন সিকোয়েন্স প্রদান করে।
(filter odd? [1 2 3 4 5])
; আউটপুট: (1 3 5)এখানে, filter কেবল বিজোড় সংখ্যাগুলো নির্বাচন করছে।
৫. repeatedly এবং iterate ফাংশন
repeatedly এবং iterate ফাংশন নির্দিষ্ট সংখ্যক পুনরাবৃত্তি চালাতে ব্যবহৃত হয়।
repeatedly: একটি ফাংশন নেয় এবং এটি নির্দিষ্ট সংখ্যক বার চালায়।
(take 5 (repeatedly #(rand-int 10))) ; আউটপুট: (যেকোনো ৫টি র্যান্ডম সংখ্যা ০-৯ এর মধ্যে)iterate: একটি ফাংশন এবং একটি প্রাথমিক মান নেয়, এবং প্রতিটি ইটারেশনে আগের ফলাফলের উপর ফাংশন প্রয়োগ করে।
(take 5 (iterate inc 0)) ; আউটপুট: (0 1 2 3 4)
সারসংক্ষেপ
ক্লোজারে loop এবং recur রিকার্সনভিত্তিক লুপিং প্রদান করে। for, doseq, map, reduce, এবং filter ফাংশন ব্যবহার করে উচ্চ স্তরের লুপিং এবং ইটারেশন করা যায়। এই টুলগুলো ক্লোজারকে ফাংশনাল প্রোগ্রামিংয়ের জন্য আরও উপযোগী করে তোলে।
রিকার্সন (Recursion) এবং ইটারেশন (Iteration) এর ধারণা
রিকার্সন এবং ইটারেশন প্রোগ্রামিংয়ে বারবার পুনরাবৃত্তি করে কাজ সম্পন্ন করার দুটি পদ্ধতি। এই দুই পদ্ধতি কার্যক্ষমতা এবং প্রয়োগের ক্ষেত্রে পার্থক্য রয়েছে। চলুন রিকার্সন এবং ইটারেশনের ধারণা, প্রয়োগ এবং পার্থক্য সম্পর্কে আলোচনা করা যাক।
রিকার্সন (Recursion)
রিকার্সন একটি প্রোগ্রামিং পদ্ধতি যেখানে একটি ফাংশন নিজেই নিজেকে বারবার কল করে কাজ সম্পন্ন করে। রিকার্সনে সাধারণত একটি বেস কেস (যেখানে রিকার্সন থামে) এবং একটি রিকার্সিভ কেস (যেখানে ফাংশন নিজেকে পুনরায় কল করে) থাকে। রিকার্সন সাধারণত জটিল সমস্যাগুলিকে সরল এবং পুনরাবৃত্তভাবে সমাধান করার জন্য ব্যবহৃত হয়।
উদাহরণ: ফ্যাক্টরিয়াল গণনা
ফ্যাক্টরিয়াল গণনার জন্য একটি রিকার্সিভ ফাংশন লেখা যেতে পারে যেভাবে:
(defn factorial [n]
(if (<= n 1)
1
(* n (factorial (dec n)))))এখানে, factorial ফাংশনটি নিজেই নিজেকে কল করছে যতক্ষণ পর্যন্ত n এর মান ১ বা তার চেয়ে কম না হয়। এই ফাংশনটি n এর মানকে প্রতি রিকার্সিভ কলে কমিয়ে দেয় এবং অবশেষে ফ্যাক্টরিয়াল রিটার্ন করে।
ইটারেশন (Iteration)
ইটারেশন একটি পদ্ধতি যেখানে একটি নির্দিষ্ট শর্ত পর্যন্ত একটি লুপ বারবার চালানো হয়। ইটারেশন সাধারণত for, while, বা loop কন্সট্রাক্ট ব্যবহার করে করা হয়। ইটারেশন লুপের মাধ্যমে কাজ সম্পন্ন করে এবং সাধারণত কম মেমোরি ব্যবহার করে, কারণ এটি স্ট্যাক ফ্রেমের উপর নির্ভর করে না।
উদাহরণ: ফ্যাক্টরিয়াল গণনা
ফ্যাক্টরিয়াল গণনার জন্য একটি ইটারেটিভ পদ্ধতি লেখা যেতে পারে এভাবে:
(defn factorial [n]
(loop [i n, acc 1]
(if (<= i 1)
acc
(recur (dec i) (* acc i)))))এখানে loop এবং recur ব্যবহার করে একটি লুপ তৈরি করা হয়েছে। i দ্বারা প্রতিবার n এর মান কমানো হয় এবং acc এর সাথে গুণ করা হয়। যখন i এর মান ১ বা তার চেয়ে কম হয়ে যায়, তখন acc রিটার্ন হয়।
রিকার্সন বনাম ইটারেশন: তুলনা
| বৈশিষ্ট্য | রিকার্সন | ইটারেশন |
|---|---|---|
| কাজের পদ্ধতি | ফাংশন নিজেই নিজেকে পুনরায় কল করে | একটি নির্দিষ্ট শর্ত পর্যন্ত লুপ চলতে থাকে |
| স্ট্যাক ব্যবহার | প্রতিটি রিকার্সিভ কল একটি নতুন স্ট্যাক ফ্রেম তৈরি করে | লুপ একই স্ট্যাক ফ্রেমে কাজ সম্পন্ন করে |
| কোড সরলতা | ছোট এবং সহজ কোডের জন্য উপযুক্ত | লজিক সহজ হলে সরাসরি ব্যবহার করা যায় |
| কার্যক্ষমতা | বড় ইনপুটে স্ট্যাক ওভারফ্লো হতে পারে | বড় ইনপুটে মেমোরি এবং সময় সাশ্রয়ী |
| ব্যবহার ক্ষেত্র | জটিল ও বিভাজ্য সমস্যাগুলিতে কার্যকর | সাধারণ পুনরাবৃত্তিমূলক কাজের জন্য উপযুক্ত |
কোন পরিস্থিতিতে কোনটি ব্যবহার করবেন?
- রিকার্সন সাধারণত ব্যবহার করা হয় এমন সমস্যাগুলোর জন্য যেখানে সমাধানটি নিজেই পুনরাবৃত্তির উপর ভিত্তি করে থাকে, যেমন গাছের স্ট্রাকচার বা জটিল বিভাজন। রিকার্সন কোড সহজ এবং সংক্ষিপ্ত করে।
- ইটারেশন সাধারণত ব্যবহার করা হয় যেখানে নির্দিষ্ট সংখ্যক পুনরাবৃত্তির মাধ্যমে কাজ সম্পন্ন করা সম্ভব। এটি স্ট্যাক ওভারফ্লো প্রতিরোধ করে এবং বড় ইনপুটের জন্য কার্যক্ষম।
সারসংক্ষেপ
রিকার্সন এবং ইটারেশন উভয়ই পুনরাবৃত্তিমূলক কাজের জন্য ব্যবহৃত হয়, তবে প্রয়োগের ক্ষেত্রে এদের মধ্যে পার্থক্য রয়েছে। রিকার্সন জটিল সমস্যার সমাধানে উপযোগী, যখন ইটারেশন বড় ডেটাসেটের জন্য মেমোরি দক্ষতা বৃদ্ধি করে।
loop/recur এর মাধ্যমে Tail-Recursive Looping
ক্লোজারে (Clojure) tail-recursive looping বাস্তবায়ন করার জন্য loop এবং recur ব্যবহার করা হয়। এই দুটি ফাংশন একসাথে কাজ করে এবং tail recursion এর সুবিধা প্রদান করে, যেখানে রিকার্সিভ কলের শেষ অংশে কোনো অতিরিক্ত কাজ থাকে না, ফলে মেমোরি ব্যবহার সাশ্রয়ী হয় এবং স্ট্যাক ওভারফ্লো এর ঝুঁকি কমে।
loop/recur কী?
loop: এটি একটি লুপের মতো ব্যবহৃত হয়, যা নির্দিষ্ট সংখ্যা বা শর্ত পূর্ণ না হওয়া পর্যন্ত পুনরাবৃত্তি করতে সাহায্য করে। এটি চলতে থাকা প্রোগ্রাম কনট্রোলের জন্য কিছু স্থির মান বা অবস্থান নির্ধারণ করে।recur: এটিloopবা রিকার্সিভ ফাংশনের মধ্যে নিজেকে পুনরায় কল করতে ব্যবহৃত হয়। এটি স্ট্যাক ওভারফ্লো সমস্যা ছাড়া কার্যকরীভাবে টেইল রিকার্সন তৈরি করতে সাহায্য করে, কারণrecurকোনো নতুন স্ট্যাক ফ্রেম তৈরি না করে বর্তমান ফ্রেমে কাজ চালিয়ে যায়।
loop এবং recur এর মাধ্যমে Tail-Recursive Looping উদাহরণ
উদাহরণ: ফ্যাক্টরিয়াল গণনা
(defn factorial [n]
(loop [acc 1
num n]
(if (<= num 1)
acc
(recur (* acc num) (dec num)))))এখানে loop দিয়ে একটি লুপ শুরু করা হয়েছে এবং recur এর মাধ্যমে ফাংশনকে আবার কল করা হয়েছে, কিন্তু কোনো নতুন স্ট্যাক ফ্রেম তৈরি না করে। acc একটি অ্যাকিউমুলেটর (accumulator) হিসেবে কাজ করছে, যা ফ্যাক্টরিয়াল গণনার জন্য আগের ফলাফলের সাথে বর্তমান মানকে গুণ করছে। এইভাবে, শেষের রিকার্সন কলের পর কোনো অতিরিক্ত কাজ হয় না, এবং মেমোরি ব্যবহার দক্ষ থাকে।
ব্যাখ্যা:
loopএর মধ্যেaccএবংnumনামের দুটি ভ্যারিয়েবল নির্ধারণ করা হয়েছে।accহচ্ছে ফ্যাক্টরিয়াল গণনার জন্য ইনিশিয়াল মান, এবংnumহচ্ছে ডেটার বর্তমান মান।- শর্ত
(<= num 1)চেক করা হচ্ছে, যদিnum1 এর সমান বা ছোট হয়, তবেaccরিটার্ন করা হবে, অন্যথায়recurদিয়ে পুনরায় কল করা হবে। recurপরবর্তী রিকার্সন কলের জন্য অ্যাকিউমুলেটরaccআপডেট করে এবংnumএর মান 1 কমায়। এতে কোনো নতুন স্ট্যাক ফ্রেম তৈরি হয় না এবং এই কল বর্তমান ফ্রেমে সম্পন্ন হয়।
উদাহরণ: ফিবোনাচি সিরিজ
(defn fibonacci [n]
(loop [a 0
b 1
count n]
(if (<= count 0)
a
(recur b (+ a b) (dec count)))))এখানে loop এবং recur এর মাধ্যমে ফিবোনাচি সিরিজ গণনা করা হচ্ছে। a এবং b ফিবোনাচি সিরিজের আগের দুটি মান, এবং count হলো ফিবোনাচি সংখ্যার অবস্থান।
ব্যাখ্যা:
loop-এ তিনটি ভ্যারিয়েবল:a,b, এবংcountব্যবহৃত হচ্ছে।aএবংbফিবোনাচি সিরিজের দুটি আগের মান, এবংcountবাকি পদ সংখ্যা।- শর্ত
(<= count 0)চেক করা হয়, যদিcount0 বা তার চেয়ে ছোট হয়, তখনaরিটার্ন করা হয়, যা ফিবোনাচি সংখ্যার মান। recurপরবর্তী রিকার্সন কলের জন্যaএবংbএর মান আপডেট করে, এবংcountএর মান 1 কমায়।
loop/recur এর সুবিধা
- মেমোরি দক্ষতা:
recurএর মাধ্যমে কোনো নতুন স্ট্যাক ফ্রেম তৈরি না হওয়ায়, মেমোরি ব্যবহারের সমস্যা যেমন স্ট্যাক ওভারফ্লো এড়ানো যায়। - স্ট্যাক ওভারফ্লো থেকে মুক্তি: রিকার্সন সাধারণত গভীর স্ট্যাক ফ্রেম তৈরি করতে পারে, কিন্তু
loopএবংrecurএর মাধ্যমে তা কমিয়ে দেয়। - পুনঃব্যবহারযোগ্য কোড: এই কৌশলটি ফাংশনাল প্রোগ্রামিংয়ে কোড পুনঃব্যবহারযোগ্য এবং আরও কার্যকরী করে তোলে।
সারসংক্ষেপ
| বৈশিষ্ট্য | loop/recur | সাধারণ রিকার্সন |
|---|---|---|
| স্ট্যাক ব্যবস্থাপনা | স্ট্যাক ফ্রেম পুনঃব্যবহার করে | প্রতিটি রিকার্সন কল নতুন স্ট্যাক ফ্রেম তৈরি করে |
| কার্যক্ষমতা | মেমোরি সাশ্রয়ী এবং কার্যকর | গভীর রিকার্সনে স্ট্যাক ওভারফ্লো হতে পারে |
| বৈশিষ্ট্য | টেইল রিকার্সন, মেমোরি দক্ষ | স্ট্যাক ওভারফ্লো ঝুঁকি এবং কম কার্যক্ষম |
ক্লোজারে loop এবং recur ব্যবহার করে tail-recursive looping একটি শক্তিশালী কৌশল, যা মেমোরি ব্যবহার সাশ্রয়ী এবং কার্যক্ষমভাবে পুনরাবৃত্তি সম্পাদন করতে সাহায্য করে।
সিকোয়েন্স ফাংশনসমূহ: map, filter, এবং reduce (Clojure)
ক্লোজার (Clojure) প্রোগ্রামিং ভাষায় সিকোয়েন্স ফাংশনগুলো খুবই শক্তিশালী এবং তা ডেটা পরিচালনার জন্য কার্যকরী। এর মধ্যে তিনটি গুরুত্বপূর্ণ ফাংশন হলো map, filter, এবং reduce। এগুলো ফাংশনাল প্রোগ্রামিংয়ে সাধারণত ব্যবহৃত হয় এবং সংগ্রহ (collection) থেকে তথ্য প্রক্রিয়া করতে সাহায্য করে।
১. map: সংগ্রহের উপাদানগুলো রূপান্তর করা
map ফাংশনটি একটি নির্দিষ্ট ফাংশন প্রতিটি উপাদানের ওপর প্রয়োগ করে এবং একটি নতুন সংগ্রহ (যেমন: লিস্ট, ভেক্টর) প্রদান করে, যেখানে প্রতিটি উপাদান প্রক্রিয়া করা হয়।
সিনট্যাক্স:
(map function collection)- function: একটি ফাংশন, যা সংগ্রহের প্রতিটি উপাদানের ওপর প্রয়োগ করা হবে।
- collection: একটি সংগ্রহ (যেমন: লিস্ট, ভেক্টর, সেট) যার উপাদানগুলোকে ফাংশনের মাধ্যমে প্রক্রিয়া করা হবে।
উদাহরণ: map ব্যবহার
(def numbers [1 2 3 4 5])
; প্রতিটি সংখ্যাকে ২ দিয়ে গুণ করা
(def doubled (map #(* 2 %) numbers))
(doubled) ; আউটপুট: (2 4 6 8 10)এখানে, #(* 2 %) একটি অ্যনোনিমাস ফাংশন যা প্রতিটি উপাদানকে ২ দিয়ে গুণ করে। নতুন সিকোয়েন্সটি হলো (2 4 6 8 10)।
২. filter: শর্তানুযায়ী উপাদান নির্বাচন করা
filter ফাংশনটি একটি শর্ত (predicate) ব্যবহার করে একটি সংগ্রহের উপাদানগুলো থেকে শুধু সেই উপাদানগুলো নির্বাচন করে যেগুলো শর্ত পূরণ করে।
সিনট্যাক্স:
(filter predicate collection)- predicate: একটি শর্ত (ফাংশন), যা নির্ধারণ করে কোন উপাদানগুলো সংরক্ষণ করতে হবে।
- collection: একটি সংগ্রহ (যেমন: লিস্ট, ভেক্টর) যেখান থেকে শর্ত পূর্ণ করা উপাদানগুলো বের করা হবে।
উদাহরণ: filter ব্যবহার
(def numbers [1 2 3 4 5 6])
; শুধুমাত্র যেগুলি সোজা সংখ্যা (even) তা বের করা
(def even-numbers (filter even? numbers))
(even-numbers) ; আউটপুট: (2 4 6)এখানে, even? ফাংশনটি শর্ত হিসেবে ব্যবহৃত হচ্ছে, যার মাধ্যমে শুধুমাত্র সোজা (even) সংখ্যাগুলো বের করা হয়েছে।
৩. reduce: উপাদানগুলোর উপর একটি একক মান অর্জন করা
reduce ফাংশনটি একটি সংগ্রহের উপাদানগুলোকে একটি একক মানে (যেমন: যোগফল, গুণফল, ইত্যাদি) পরিণত করতে ব্যবহৃত হয়। এটি একটি একক রেজাল্ট তৈরি করতে দুটি উপাদানকে একসাথে প্রক্রিয়া করে এবং তা পরবর্তী উপাদানের সঙ্গে চালিয়ে যায়।
সিনট্যাক্স:
(reduce function collection)- function: একটি ফাংশন, যা দুটি উপাদানকে একসঙ্গে প্রক্রিয়া করে একটি একক মান তৈরি করবে।
- collection: একটি সংগ্রহ (যেমন: লিস্ট, ভেক্টর) যার উপাদানগুলোর উপর রিডিউস ফাংশন কাজ করবে।
উদাহরণ: reduce ব্যবহার
(def numbers [1 2 3 4 5])
; সব সংখ্যার যোগফল বের করা
(def sum (reduce + numbers))
(sum) ; আউটপুট: 15এখানে, + ফাংশনটি সমস্ত সংখ্যার উপর প্রয়োগ করা হয়েছে এবং সেগুলোর যোগফল ১৫ বের করা হয়েছে।
সারসংক্ষেপ
| ফাংশন | কাজ | উদাহরণ |
|---|---|---|
map | প্রতিটি উপাদানের উপর একটি ফাংশন প্রয়োগ করে একটি নতুন সংগ্রহ তৈরি করা | map #(* 2 %) numbers |
filter | একটি শর্তের ভিত্তিতে উপাদানগুলো নির্বাচন করা | filter even? numbers |
reduce | সমস্ত উপাদানগুলো একটি একক মানে রূপান্তর করা | reduce + numbers |
এই ফাংশনগুলো ক্লোজারে একটি শক্তিশালী সরঞ্জাম হিসেবে কাজ করে, যা সংগ্রহের উপাদানগুলোকে রূপান্তর, ফিল্টার এবং কম্পাইল করার জন্য খুবই কার্যকর।
List এবং Vector এর সাথে Iteration Techniques
ক্লোজার (Clojure) প্রোগ্রামিং ভাষায়, List এবং Vector দুটি গুরুত্বপূর্ণ ডেটা কাঠামো, যা ডেটা সংরক্ষণ এবং পরিচালনার জন্য ব্যবহার হয়। এই ডেটা কাঠামোগুলির সাথে ইটারেশন (Iteration) করার জন্য ক্লোজার বিভিন্ন শক্তিশালী ফাংশন সরবরাহ করে। এর মাধ্যমে আমরা সহজেই প্রতিটি উপাদান এক্সেস, পরিবর্তন এবং প্রক্রিয়া করতে পারি।
ক্লোজারে লিস্ট এবং ভেক্টরের সাথে ইটারেশন করার জন্য বিভিন্ন ফাংশন এবং কৌশল রয়েছে, যেমন map, filter, reduce, doseq, for, ইত্যাদি।
১. List এবং Vector এর মধ্যে পার্থক্য
- List: লিনিয়ার লিঙ্কড লিস্ট। এতে ডেটা সংরক্ষণ করা হয় এবং লিস্টের প্রথম আইটেম থেকে ইটারেশন শুরু হয়।
- Vector: ইমিউটেবল, দ্রুত অ্যাক্সেসযোগ্য ডেটা কাঠামো, যা ইনডেক্সিংয়ের মাধ্যমে দ্রুত এলিমেন্ট এক্সেসের সুবিধা দেয়।
২. map ফাংশন
map একটি খুবই শক্তিশালী ফাংশন যা একটি ফাংশনকে লিস্ট বা ভেক্টরের প্রতিটি উপাদানের উপর প্রয়োগ করে একটি নতুন ডেটা কাঠামো তৈরি করে। এটি ফাংশনাল প্রোগ্রামিংয়ের একটি গুরুত্বপূর্ণ অংশ।
উদাহরণ: map ব্যবহার করে লিস্ট এবং ভেক্টরের উপর ইটারেশন
(def my-list '(1 2 3 4))
(def my-vector [1 2 3 4])
; লিস্টের প্রতি উপাদানে ২ যোগ করা
(map #( + % 2) my-list) ; আউটপুট: (3 4 5 6)
; ভেক্টরের প্রতি উপাদানে ২ যোগ করা
(map #( + % 2) my-vector) ; আউটপুট: (3 4 5 6)এখানে, map ফাংশনটি একটি অ্যানোনিমাস ফাংশন (lambda) ব্যবহার করে লিস্ট এবং ভেক্টরের প্রতিটি উপাদানের ওপর + 2 অপারেশন চালায়।
৩. filter ফাংশন
filter ফাংশনটি একটি শর্তের ভিত্তিতে লিস্ট বা ভেক্টর থেকে নির্বাচিত উপাদানগুলি ফিল্টার করে এবং নতুন একটি লিস্ট প্রদান করে। এটি শুধুমাত্র সেই উপাদানগুলো রাখে যেগুলি শর্ত পূরণ করে।
উদাহরণ: filter ব্যবহার করে লিস্ট এবং ভেক্টরের উপর ইটারেশন
; লিস্টের মধ্যে ৩ এর বড় সংখ্যাগুলো বের করা
(filter #(> % 3) my-list) ; আউটপুট: (4)
; ভেক্টরের মধ্যে ৩ এর বড় সংখ্যাগুলো বের করা
(filter #(> % 3) my-vector) ; আউটপুট: (4)এখানে, filter ফাংশনটি একটি শর্ত (> 3) চেক করে এবং শুধুমাত্র সেই উপাদানগুলো রেখে দেয় যেগুলি শর্ত পূরণ করে।
৪. reduce ফাংশন
reduce ফাংশনটি একটি অ্যাকিউমুলেটর ব্যবহার করে লিস্ট বা ভেক্টরের উপাদানগুলির উপর একটি অ্যাগ্রিগেট অপারেশন (যেমন যোগ, গুণ, ইত্যাদি) করে। এটি একক মানে রেজাল্ট প্রদান করে।
উদাহরণ: reduce ব্যবহার করে লিস্ট এবং ভেক্টরের উপর ইটারেশন
; লিস্টের উপাদানগুলোর যোগফল বের করা
(reduce + my-list) ; আউটপুট: 10
; ভেক্টরের উপাদানগুলোর যোগফল বের করা
(reduce + my-vector) ; আউটপুট: 10এখানে, reduce ফাংশনটি + অপারেশন ব্যবহার করে লিস্ট এবং ভেক্টরের উপাদানগুলির যোগফল হিসাব করে।
৫. doseq ফাংশন
doseq একটি ইটারেটিভ ফাংশন যা সাইড-এফেক্ট তৈরি করতে ব্যবহৃত হয়, যেমন একটি ভেক্টর বা লিস্টের প্রতিটি উপাদানে কিছু কাজ করা (উদাহরণস্বরূপ, প্রিন্ট করা)। এটি মূলত লুপিংয়ের মতো কাজ করে।
উদাহরণ: doseq ব্যবহার করে লিস্ট এবং ভেক্টরের উপর ইটারেশন
; লিস্টের প্রতিটি উপাদান প্রিন্ট করা
(doseq [x my-list]
(println x)) ; আউটপুট: 1 2 3 4
; ভেক্টরের প্রতিটি উপাদান প্রিন্ট করা
(doseq [x my-vector]
(println x)) ; আউটপুট: 1 2 3 4এখানে, doseq লিস্ট এবং ভেক্টরের প্রতিটি উপাদানকে প্রিন্ট করে।
৬. for ফাংশন
for একটি কম্প্যাক্ট ফাংশন যা একটি পদ্ধতির মাধ্যমে একাধিক শর্ত এবং সিকোয়েন্সের উপর ইটারেশন করতে ব্যবহৃত হয়। এটি একটি লিস্ট কম্প্রিহেনশন স্টাইল ফাংশন, যেখানে শর্ত, ফিল্টার এবং মডিফিকেশন একত্রে ব্যবহৃত হয়।
উদাহরণ: for ব্যবহার করে লিস্ট এবং ভেক্টরের উপর ইটারেশন
; লিস্টের সকল উপাদানে ২ যোগ করা
(for [x my-list]
(+ x 2)) ; আউটপুট: (3 4 5 6)
; ভেক্টরের সকল উপাদানে ২ যোগ করা
(for [x my-vector]
(+ x 2)) ; আউটপুট: (3 4 5 6)এখানে, for ফাংশনটি লিস্ট বা ভেক্টরের প্রতিটি উপাদানে + 2 অপারেশন চালিয়ে নতুন লিস্ট তৈরি করছে।
৭. doseq বনাম for
| ফাংশন | উদ্দেশ্য | ব্যবহার |
|---|---|---|
doseq | সাইড-এফেক্ট তৈরি করতে ব্যবহৃত (উদাহরণস্বরূপ, প্রিন্ট করা) | doseq ব্যবহৃত হয় যখন ফলাফল প্রয়োজন নয়, শুধু কাজটি করা দরকার |
for | নতুন সংগ্রহ তৈরি করতে ব্যবহৃত | for ব্যবহৃত হয় যখন নতুন ডেটা কাঠামো তৈরি করতে হয় |
সারসংক্ষেপ
ক্লোজারে List এবং Vector এর সাথে ইটারেশন করার জন্য বিভিন্ন শক্তিশালী কৌশল ও ফাংশন রয়েছে:
map: প্রতিটি উপাদানে একটি ফাংশন প্রয়োগ করে একটি নতুন সংগ্রহ তৈরি করে।filter: শর্ত অনুসারে উপাদানগুলো ফিল্টার করে একটি নতুন সংগ্রহ তৈরি করে।reduce: একটি অ্যাকিউমুলেটর ব্যবহার করে উপাদানগুলোর উপর একটি অ্যাগ্রিগেট অপারেশন করে।doseq: সাইড-এফেক্ট তৈরির জন্য ব্যবহৃত (যেমন প্রিন্ট করা)।for: লিস্ট কম্প্রিহেনশন স্টাইলের ফাংশন, যেখানে শর্ত এবং ফিল্টার ব্যবহৃত হয়।
এই ফাংশনগুলো ক্লোজারে লিস্ট এবং ভেক্টরের উপর ইটারেশন ও ডেটা ম্যানিপুলেশনের জন্য খুবই শক্তিশালী এবং নমনীয়।
Read more