`Set` অবজেক্ট

এই আর্টিকেলটি Set অবজেক্ট ব্যাখ্যা করে।

আমরা ব্যবহারিক উদাহরণের মাধ্যমে Set অবজেক্ট ব্যাখ্যা করবো।

YouTube Video

Set অবজেক্ট

Set একটি বিল্ট-ইন অবজেক্ট, যা ইউনিক অর্থাৎ অনন্য, পুনরাবৃত্তিহীন মানের সংগ্রহ ব্যবস্থাপনা করতে ব্যবহৃত হয়। এটি আপনাকে ডুপ্লিকেট অপসারণ এবং অস্তিত্ব যাচাই করার কাজ অ্যারে থেকে অনেক সহজে করতে দেয়, এবং ইউনিয়ন বা ইন্টারসেকশনের মতো সেট অপারেশনগুলো সাধারণভাবে বাস্তবায়ন করতে সুবিধা দেয়।

মৌলিক ধারণা: Set তৈরি ও ব্যবহার

প্রথমে আমরা দেখবো কিভাবে একটি Set তৈরি করা যায়, উপাদান যোগ-বিয়োগ, অস্তিত্ব যাচাই এবং এর আকার (size) জানা যায়।

নিচে একটি মৌলিক নমুনা দেওয়া হয়েছে যেখানে একটি নতুন Set তৈরি, এবং add, has, delete, ও size ব্যবহার দেখানো হয়েছে।

 1// Create a Set and demonstrate add, has, delete, and size
 2const s = new Set();
 3
 4s.add(1);
 5s.add(2);
 6s.add(2); // duplicate, ignored
 7
 8console.log(s.has(1)); // true
 9console.log(s.has(3)); // false
10
11s.delete(2);
12console.log(s.size); // 1
13
14console.log([...s]); // [1]
  • এই কোডে দেখানো হয়েছে, Set স্বয়ংক্রিয়ভাবে সদৃশ সাধারন মানগুলো সরিয়ে দেয়, এবং আপনি size ব্যবহার করে উপাদানের সংখ্যা পেতে পারেন।

ইটারেশন পদ্ধতি

Set ইটারেবল, তাই আপনি এটি for...of বা forEach ব্যবহার করে লুপ করতে পারেন। উপাদানগুলোর ক্রম হল ইনসার্শনের (যোগ করার) ক্রম।

এখানে for...of এবং forEach ব্যবহারের কিছু সাধারণ উপায় দেখানো হলো।

 1// Iterate a Set with for...of and forEach
 2const s = new Set(['a', 'b', 'c']);
 3
 4for (const v of s) {
 5  console.log('for...of:', v);
 6}
 7
 8s.forEach((value, sameValue, setRef) => {
 9  // Note: second arg is same as first for Set API to match Map signature
10  console.log('forEach:', value);
11});
  • forEach-এর জন্য কলব্যাক স্বাক্ষর হল value, value, set (Map-এর সাথে সামঞ্জস্য রাখার জন্য), তবে প্রকৃতপক্ষে আপনি সাধারণত শুধুমাত্র প্রথম value আর্গুমেন্টটি ব্যবহার করেন।

অ্যারে ও সেট-এর মধ্যে রূপান্তর (ডুপ্লিকেট অপসারণে সহায়ক)

এখানে আমরা দেখাবো কিভাবে একটি অ্যারে থেকে ডুপ্লিকেট সরিয়ে ফেলা যায় এবং কীভাবে একটি Set-কে পুনরায় অ্যারেতে রূপান্তর করা যায়।

নিচে দেখানো হয়েছে কিভাবে একটি অ্যারেকে Set-এর মধ্যে দিয়ে দিলে ডুপ্লিকেট সরানো যায়।

1// Deduplicate an array using Set
2const arr = [1, 2, 2, 3, 3, 3];
3const deduped = [...new Set(arr)];
4console.log(deduped); // [1, 2, 3]
5
6// Convert a Set to an array using Array.from
7const s = new Set([4, 5, 6]);
8const arrFromSet = Array.from(s);
9console.log(arrFromSet); // [4, 5, 6]
  • এই প্যাটার্নটি সংক্ষিপ্ত ও দ্রুত, তাই অ্যারের ডুপ্লিকেট অপসারণের জন্য এটি প্রায়ই ব্যবহৃত হয়। এটি বিশেষ করে প্রিমিটিভ মানের ক্ষেত্রে কার্যকর।

অবজেক্ট এবং রেফারেন্স ব্যবস্থাপনা

Set-এর অবজেক্টগুলো রেফারেন্স দ্বারা তুলনা (compare) করা হয়, তাই একই কন্টেন্ট হলেও আলাদা ইনস্ট্যান্সকে পৃথক উপাদান হিসেবে ধরা হয়।

নিম্নোক্ত কোডে দেখানো হয়েছে কী ঘটে যখন আপনি অবজেক্টকে Set-এ যোগ করেন।

 1// Objects are compared by reference in a Set
 2const obj1 = { x: 1 };
 3const obj2 = { x: 1 };
 4
 5const s = new Set();
 6s.add(obj1);
 7s.add(obj2);
 8
 9console.log(s.size); // 2 (different references)
10console.log(s.has(obj1)); // true
11console.log(s.has({ x: 1 })); // false (different object)
  • অবজেক্টে ডুপ্লিকেট নির্ধারণ (ডিটেকশন) হয় রেফারেন্স আইডেন্টিটির উপর ভিত্তি করে, তাই কেবল কন্টেন্ট দিয়ে ডুপ্লিকেট অপসারণ করতে চাইলে সিরিয়ালাইজ বা অন্যভাবে প্রক্রিয়া করতে হবে।

বিশেষ মান: NaN এবং -0/+0 এর ব্যবস্থাপনা

Set মানের সমতা বিবেচনায় Same-value-zero তুলনা নিয়ম ব্যবহার করে। সংখ্যা সংক্রান্ত এই তুলনা পদ্ধতির বৈশিষ্ট্যসমূহ হলো:।

  • NaN-কে NaN-এর সমতুল্য হিসেবে ধরা হয়।
  • পজিটিভ +0 এবং নেগেটিভ -0 আলাদা মনে করা হয় না, তাদেরকে একই মান ধরা হয়।

তাই এই মানগুলোকে Set-এ যোগ করলে নিম্নোক্ত আচরণ দেখা যায়:।

 1// NaN and zero behavior in Set
 2const s = new Set();
 3
 4s.add(NaN);
 5s.add(NaN);
 6console.log(s.size); // 1 (NaN considered the same)
 7
 8s.add(+0);
 9s.add(-0);
10console.log(s.size); // still 2 (NaN + 0)
11console.log([...s]); // [NaN, 0] (order may vary but only one zero)
  • সাধারণ তুলনায় (NaN === NaN) ফলাফল false ফিরে আসে, কিন্তু Set-এর মধ্যে সব NaN-কে একই মান ধরা হয়।
  • +0 এবং -0 কে গাণিতিকভাবে আলাদা করা যায়, কিন্তু Set-এ তাদেরকে শুধু 0 হিসেবেই দেখা হয়।
  • ফলে, Set-এ কেবলমাত্র একটি NaN এবং একটি 0 রয়ে যায়।
  • Set-এর তুলনা নিয়ম Object.is-এর মতো, তবে পুরোপুরি অভিন্ন নয়Object.is(+0, -0) হলে false ফিরে আসে, কিন্তু Set-এ তাদেরকে সমান মনে করা হয়। অনুগ্রহ করে এই পার্থক্যটি লক্ষ্য রাখুন।

সাধারণ সুবিধা: সেট কার্যক্রম (ইউনিয়ন, ইন্টারসেকশন, ডিফারেন্স)

Set ব্যবহার করে সেট কার্যক্রম আরও পরিষ্কারভাবে লেখা যায়। নিচে কিছু সাধারণ বাস্তবায়নের উদাহরণ দেওয়া হল।

এখানে union, intersection, এবং difference ফাংশনের উদাহরণ দেওয়া হল।

 1// Set operations: union, intersection, difference
 2function union(a, b) {
 3  return new Set([...a, ...b]);
 4}
 5
 6function intersection(a, b) {
 7  return new Set([...a].filter(x => b.has(x)));
 8}
 9
10function difference(a, b) {
11  return new Set([...a].filter(x => !b.has(x)));
12}
13
14// Demo
15const A = new Set([1, 2, 3]);
16const B = new Set([3, 4, 5]);
17
18console.log('union', [...union(A, B)]); // [1,2,3,4,5]
19console.log('intersection', [...intersection(A, B)]); // [3]
20console.log('difference A\\B', [...difference(A, B)]); // [1,2]
  • Set এবং অ্যারে একত্রে ব্যবহার করে ফিল্টার ব্যবহার করে সহজেই সেট কার্যক্রম লেখা যায়। বড় ডেটাসেটের ক্ষেত্রে, has-এর O(1) কর্মদক্ষতা অপারেশন দ্রুত করে তোলে।

ব্যবহারিক উদাহরণ: অ্যারে ডিফারেন্স বের করা (যোগ/অপসারিত আইটেম সনাক্তকরণ)

নিম্নের উদাহরণে দেখানো হয়েছে কিভাবে দুটি অ্যারে (পুরাতন তালিকা এবং নতুন তালিকা) মধ্যে ডিফারেন্স নির্ণয়ে Set ব্যবহার করা যায়। এতে আপনি সহজেই জানতে পারবেন কোন উপাদান যোগ হয়েছে, আর কোনটি সরানো হয়েছে।

 1// Find added and removed items between two arrays
 2function diffArrays(oldArr, newArr) {
 3  const oldSet = new Set(oldArr);
 4  const newSet = new Set(newArr);
 5
 6  const added = [...newSet].filter(x => !oldSet.has(x));
 7  const removed = [...oldSet].filter(x => !newSet.has(x));
 8
 9  return { added, removed };
10}
11
12const oldList = [1, 2, 3];
13const newList = [2, 3, 4, 5];
14
15console.log(diffArrays(oldList, newList));
16// { added: [4,5], removed: [1] }
  • আইডি তালিকা, ট্যাগ তালিকা বা অনুরূপ স্থানে পার্থক্য সনাক্তকরণে এই পদ্ধতি খুবই সুবিধাজনক। প্রিমিটিভ মানের সঙ্গে এটি ব্যবহার সবচেয়ে সহজ।

WeakSet ও Set-এর পার্থক্য (মেমরি ব্যবস্থাপনা)

WeakSet, Set-এর অনুরূপ, তবে এটি দুর্বল রেফারেন্স ব্যবহার করে, যার ফলে এর আইটেমগুলো গার্বেজ কালেক্ট করা যেতে পারে। নিম্নে WeakSet-এর মৌলিক ব্যবহার দেখানো হয়েছে।

1// WeakSet basics (objects only, not iterable)
2const ws = new WeakSet();
3let obj = { id: 1 };
4ws.add(obj);
5
6console.log(ws.has(obj)); // true
7
8obj = null; // Now the object is eligible for GC; WeakSet won't prevent collection

WeakSet শুধুমাত্র অবজেক্ট রাখতে পারে এবং এর উপর ইটারেট (loop) করা যায় না। নিচে WeakSet-এর সীমাবদ্ধতার উদাহরণ: এটি কেবল অবজেক্ট রাখতে পারে এবং ইটারেট করা যায় না।

 1// WeakSet basics (objects only, not iterable)
 2const ws = new WeakSet();
 3
 4// --- Only objects can be added ---
 5try {
 6	ws.add(1); // number
 7} catch (e) {
 8	console.log("Error: WeakSet can only store objects. Adding a number is not allowed.");
 9}
10
11try {
12	ws.add("text"); // string
13} catch (e) {
14	console.log("Error: WeakSet can only store objects. Adding a string is not allowed.");
15}
16
17// --- WeakSet is not iterable ---
18try {
19	for (const value of ws) {
20		console.log(value);
21	}
22} catch (e) {
23	console.log("Error: WeakSet is not iterable. You cannot use for...of to loop over its elements.");
24}
25
26// --- Cannot convert to array ---
27try {
28	console.log([...ws]);
29} catch (e) {
30	console.log("Error: WeakSet cannot be converted to an array because it does not support iteration.");
31}
32
33// The object becomes eligible for garbage collection
34let obj = { id: 1 };
35ws.add(obj);
36obj = null;
  • WeakSet স্বল্প সময়ের জন্য অবজেক্টের উপস্থিতি ট্র্যাক করতে কাজে লাগে, তবে আপনি এর উপাদান গুনতে বা দেখতে পারবেন না।

পারফরমেন্স ও কখন ব্যবহার করবেন তা নির্ধারণ

Set ব্যবহার করবেন কিনা সিদ্ধান্ত নেওয়ার আগে এর পারফরম্যান্সের বৈশিষ্ট্য ও আপনার ডেটার ধরন সম্পর্কে জানা জরুরি।

  • has, add, এবং delete সাধারণত গড়ে O(1) পারফরমেন্সে চলে। তাই আপনি যদি প্রায়ই অস্তিত্ব যাচাই বা ডুপ্লিকেট সরাতে চান, তাহলে অ্যারের তুলনায় Set অধিকতর উপকারী।
  • কন্টেন্ট (মান) ভিত্তিক অবজেক্ট ডুপ্লিকেট অপসারণের ক্ষেত্রে সতর্ক থাকুন। Set রেফারেন্স দ্বারা তুলনা করে, তাই এমন ক্ষেত্রে আপনি ID বা অন্যান্য কী ব্যবহার করুন, অথবা অবজেক্টকে প্রিমিটিভ মানে সিরিয়ালাইজ করে তারপর সেটে ব্যবহার করুন।
  • Set বিশেষত ছোট ও মাঝারি আকারের সংগ্রহে কোডের পাঠযোগ্যতা (readability) বাড়াতে সহায়ক। অন্যদিকে, আপনি যদি অনেক বড় উপাদান পরিচালনা করেন বা অ্যারে ও সেট-এর মধ্যে বারবার রূপান্তর করেন, তাহলে বাস্তবিকভাবে বেন্চমার্ক (benchmark) ও টেস্ট করার পরামর্শ দেওয়া হয়

সাধারণ সমস্যাসমূহ (pitfalls)

Set সুবিধাজনক, তবে এর স্পেসিফিকেশন সম্পর্কে না জানলে অপ্রত্যাশিত আচরণে বিভ্রান্ত হতে পারেন। খেয়াল রাখার জন্য কিছু সাধারণ বিষয় নিচে দেওয়া হল:।

  • অবজেক্টগুলো রেফারেন্স দ্বারা তুলনা করা হয়, তাই একই কন্টেন্ট হলেও আলাদা অবজেক্টকে ডুপ্লিকেট ধরা হয় না।
  • Set ইনসার্শন অর্ডার বজায় রাখে, তবে আপনি অ্যারের মতো ইনডেক্সের মাধ্যমে উপাদান অ্যাক্সেস করতে পারবেন না। যদি ইনডেক্স-ভিত্তিক অ্যাক্সেস করতে চান, তাহলে আগে Set-কে অ্যারেতে রূপান্তর করুন।
  • WeakSet-কে এনুমারেট (নির্দেশনা/লুপ) করা যায় না, এবং এটি শুধু অবজেক্ট সংরক্ষণ করতে পারে। মনে রাখবেন এর ব্যবহারের ক্ষেত্র সীমিত।
  • NaN-কে একই মান মনে করা হয় এবং +0-0-কে আলাদা মনে করা হয় না। এটি Same-value-zero তুলনা নিয়মের কারণে।

সারসংক্ষেপ

Set একটি সুবিধাজনক ডেটা স্ট্রাকচার, যা আপনাকে সহজেই অনন্য মানের সংগ্রহ পরিচালনা করতে দেয়। এটি ব্যবহার করে আপনি অ্যারে থেকে ডুপ্লিকেট সরাতে পারেন, দ্রুত অস্তিত্ব যাচাই করতে পারেন, বা ইউনিয়ন ও ইন্টারসেকশনসহ সেট অপারেশন সহজ ও পাঠযোগ্য কোডে বাস্তবায়ন করতে পারেন।

অন্যদিকে, অবজেক্টগুলো রেফারেন্স দ্বারা তুলনা হওয়ায়, কন্টেন্ট অনুযায়ী সমতা নির্ধারণ করতে বাড়তি ব্যবস্থা নিতে হবে।

এই বৈশিষ্ট্যগুলো বুঝে এবং সঠিকভাবে ব্যবহার করলে, Set কোডের পাঠযোগ্যতা ও রক্ষণাবেক্ষণে একটি শক্তিশালী পছন্দ হয়ে ওঠে।

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video