डुप्लिकेट एरे: यह समस्या Stack Overflow पर हजारों बार क्यों देखी गई
\n\nकल्पना करें: आप एक ऑनलाइन स्टोर बना रहे हैं, उपयोगकर्ता उत्पादों को कार्ट में जोड़ता है। लेकिन गलती से या बग के कारण, एक ही iPhone तीन बार सूची में आ जाता है। या आप डेटाबेस से टैग्स की सूची पार्स कर रहे हैं, और "JavaScript" 15 बार लगातार दिखाई देता है। क्या करें? सही जवाब है—केवल अद्वितीय मान रखें।
\n\nStack Overflow पर सवाल "Get all unique values in a JavaScript array (remove duplicates)" ने लाखों बार देखा गया है। और यह कोई संयोग नहीं है। यह समस्या सरल लगती है, लेकिन इसके पीछे कई तरीकों का एक पूरा शस्त्रागार छिपा है: आधुनिक ES6 के एक-लाइनर से लेकर filter और indexOf के साथ चालाक ट्रिक्स तक। इस लेख में हम सिर्फ तैयार समाधान नहीं देंगे, बल्कि यह भी समझाएंगे कि JavaScript इंजन के स्तर पर प्रत्येक तरीका कैसे काम करता है।
अंदर की बात जानने के लिए तैयार हैं? चलिए शुरू करते हैं!
\n\n\n\n
तरीका #1: Set — प्रदर्शन का राजा
\n\nJavaScript एरे में अद्वितीय मान प्राप्त करने का सबसे सुंदर और तेज़ तरीका Set ऑब्जेक्ट का उपयोग करना है। यह ES6 में आया था और इसी काम के लिए बनाया गया है।
const numbers = [1, 2, 2, 3, 4, 4, 5];\nconst uniqueNumbers = [...new Set(numbers)];\n\nconsole.log(uniqueNumbers); // [1, 2, 3, 4, 5]\n\nयह अंदरूनी रूप से कैसे काम करता है?
\nSet ऑब्जेक्ट केवल अद्वितीय मान संग्रहीत करता है। जब हम एरे को कंस्ट्रक्टर new Set(numbers) में पास करते हैं, तो JavaScript इंजन प्रत्येक तत्व पर जाता है और इसे एक आंतरिक हैश टेबल में जोड़ता है। यदि मान पहले से मौजूद है—तो इसे अनदेखा कर दिया जाता है। फिर स्प्रेड ऑपरेटर ... Set को वापस एरे में बदल देता है।
यह तेज़ क्यों है? क्योंकि Set में खोज और सम्मिलन O(1) (स्थिर समय) में होता है। 10,000 तत्वों वाले एरे के लिए, अन्य तरीकों की तुलना में यह बहुत बड़ा अंतर पैदा करेगा।
\n\nमहत्वपूर्ण: Set तत्वों के क्रम को बनाए रखता है, लेकिन केवल प्रिमिटिव (संख्या, स्ट्रिंग, बूलियन) के साथ काम करता है। ऑब्जेक्ट के लिए, तुलना संदर्भ (reference) से होती है, सामग्री से नहीं।
\n\nकब उपयोग करें?
\n- \n
- यदि एरे में संख्याएँ या स्ट्रिंग्स हैं। \n
- यदि बड़े एरे की प्रोसेसिंग स्पीड महत्वपूर्ण है। \n
- यदि आप आधुनिक कोड लिख रहे हैं और ES6 से नहीं डरते। \n
\n\n
तरीका #2: filter + indexOf — क्लासिक तरीका
\n\nयह विधि JavaScript की दिग्गज है। यह बिना पॉलीफिल के सभी ब्राउज़रों में काम करती है और आज भी Stack Overflow पर लोकप्रिय है।
\n\nconst numbers = [1, 2, 2, 3, 4, 4, 5];\nconst uniqueNumbers = numbers.filter((value, index, arr) => {\n return arr.indexOf(value) === index;\n});\n\nconsole.log(uniqueNumbers); // [1, 2, 3, 4, 5]\n\nतर्क की व्याख्या
\nमेथड filter एक नया एरे बनाता है, केवल उन तत्वों को रखता है जिनके लिए कॉलबैक true लौटाता है। कॉलबैक के अंदर, हम जाँचते हैं: क्या वर्तमान इंडेक्स एरे में इस मान का पहला उदाहरण है? यदि हाँ—तत्व रखें। यदि मान पहले आ चुका है—indexOf एक छोटा इंडेक्स लौटाएगा, शर्त पूरी नहीं होगी, और डुप्लिकेट हटा दिया जाएगा।
चेतावनी: indexOf हर बार एरे की शुरुआत से चलता है। इसकी जटिलता O(n²) है। छोटे एरे (1000 तत्वों तक) के लिए अंतर ध्यान देने योग्य नहीं है, लेकिन 100,000 तत्वों पर ब्राउज़र एक सेकंड के लिए हैंग हो सकता है।
कब उपयोग करें?
\n- \n
- यदि पुराने ब्राउज़रों (IE11) को सपोर्ट करना है। \n
- यदि एरे छोटा है। \n
- यदि आप "पहले उदाहरण" के तर्क को स्पष्ट रूप से दिखाना चाहते हैं। \n
\n\n
तरीका #3: reduce + एक्युमुलेटर — लचीलापन और नियंत्रण
\n\nमेथड reduce प्रक्रिया पर पूर्ण नियंत्रण देता है। हम खुद तय करते हैं कि परिणाम कैसे इकट्ठा करना है।
const numbers = [1, 2, 2, 3, 4, 4, 5];\nconst uniqueNumbers = numbers.reduce((acc, value) => {\n if (!acc.includes(value)) {\n acc.push