‘Array’ ऑब्जेक्ट

यह लेख ‘Array’ ऑब्जेक्ट के बारे में बताता है।

मैं आपको arrays के व्यावहारिक उपयोगों को आसान तरीके से एक-एक करके समझाऊँगा।

YouTube Video

‘Array’ ऑब्जेक्ट

जावास्क्रिप्ट का ‘Array’ ऑब्जेक्ट हर प्रकार की डेटा प्रोसेसिंग की नींव रखने वाली सबसे महत्वपूर्ण संरचनाओं में से एक है। आधारभूत array ऑपरेशनों से लेकर कुशल डेटा ट्रांसफॉर्मेशन के लिए उपयोगी उच्च-क्रमीय फंक्शनों तक—बहुत सी विशेषताएँ हैं जिन्हें आपको जानना चाहिए।

एरे का मूल परिचय

जावास्क्रिप्ट में, एक साथ कई मानों को संभालने के लिए ऐरे एक मौलिक डेटा संरचना है। यहाँ, हम बतायेंगे कि arrays कैसे बनते हैं और उनके तत्वों को सरल उदाहरणों के साथ कैसे पढ़ा और लिखा जा सकता है।

 1// Create arrays in different ways
 2const arr1 = [1, 2, 3];           // array literal
 3const arr2 = new Array(4, 5, 6);  // Array constructor
 4const arr3 = Array.of(7, 8, 9);   // Array.of
 5
 6console.log("arr1 created with literal.   :", arr1);
 7console.log("arr2 created with constructor:", arr2);
 8console.log("arr3 created with Array.of.  :", arr3);
 9// arr1 created with literal.   : [ 1, 2, 3 ]
10// arr2 created with constructor: [ 4, 5, 6 ]
11// arr3 created with Array.of.  : [ 7, 8, 9 ]
12
13// Access and modify elements
14let first = arr1[0];              // read element
15console.log("First element of arr1:", first);
16// First element of arr1: 1
17
18arr1[1] = 20;                     // modify element
19console.log("arr1 after modifying index 1:", arr1);
20// arr1 after modifying index 1: [ 1, 20, 3 ]
21
22const len = arr1.length;          // get length
23console.log("Length of arr1:", len);
24// Length of arr1: 3
  • यह कोड एरे बनाने के तीन तरीके, इंडेक्स द्वारा तत्वों को पढ़ने-अपडेट करने और ‘length’ प्रॉपर्टी से उसकी लंबाई पाने का तरीका दिखाता है।
  • ऐरे लिटरल्स सबसे सामान्य और पढ़ने में आसान होते हैं, और इन्हें रोज़मर्रा की स्थितियों में सबसे अधिक बार उपयोग किया जाता है।

तत्व जोड़ना और हटाना (अंत या शुरुआत में)

एरे के द्वारा आप बड़ी आसानी से तत्वों को अंत या शुरुआत में जोड़ या हटा सकते हैं। ये क्रियाएँ stacks या queues जैसी संरचनाएँ बनाने में भी बहुत काम आती हैं।

 1// Push and pop (stack-like)
 2const stack = [];
 3console.log("Initial stack:", stack);
 4
 5stack.push(1);                    // push 1
 6console.log("After push(1):", stack);
 7
 8stack.push(2);                    // push 2
 9console.log("After push(2):", stack);
10
11const last = stack.pop();         // pop -> 2
12console.log("Popped value:", last);
13console.log("Stack after pop():", stack);
14
15// Unshift and shift (queue-like)
16const queue = [];
17console.log("Initial queue:", queue);
18
19queue.push('a');                  // add to end
20console.log("After push('a'):", queue);
21
22queue.unshift('start');           // add to front
23console.log("After unshift('start'):", queue);
24
25const firstItem = queue.shift();  // remove from front
26console.log("Shifted value:", firstItem);
27console.log("Queue after shift():", queue);
28
29// Initial stack: []
30// After push(1): [ 1 ]
31// After push(2): [ 1, 2 ]
32// Popped value: 2
33// Stack after pop(): [ 1 ]
34
35// Initial queue: []
36// After push('a'): [ 'a' ]
37// After unshift('start'): [ 'start', 'a' ]
38// Shifted value: start
39// Queue after shift(): [ 'a' ]
  • ‘push’ और ‘pop’ एरे के अंत में काम करते हैं। ये stack जैसी संरचनाएँ बनाने के लिए आदर्श हैं।
  • ‘unshift’ और ‘shift’ एरे की शुरुआत में काम करते हैं। हालाँकि, शुरुआत में कार्य करने का मतलब है सभी तत्वों के इंडेक्स को अंदर से बदलना, जिससे यह एक महँगी प्रक्रिया बन जाती है।

बीच के तत्वों को संभालना (splice और slice)

एरे के बीच के तत्वों को संभालते समय, आपको यह देखना होगा कि क्या आप असली एरे को बदलना चाहते हैं या नहीं—इसी के अनुसार ‘splice’ या ‘slice’ चुनें। यदि आप केवल किसी ऐरे का एक हिस्सा निकालना चाहते हैं, तो slice का उपयोग करें; यदि आप स्वयं ऐरे को बदलना चाहते हैं, जैसे कि कोई तत्व जोड़ना या हटाना, तो splice का उपयोग करें।

 1// slice (non-destructive)
 2const nums = [0, 1, 2, 3, 4];
 3console.log("Original nums:", nums);
 4
 5const part = nums.slice(1, 4); // returns [1, 2, 3]
 6console.log("Result of nums.slice(1, 4):", part);
 7console.log("nums after slice (unchanged):", nums);
 8
 9// splice (destructive)
10const arr = [10, 20, 30, 40];
11console.log("\nOriginal arr:", arr);
12
13// remove 1 item at index 2, insert 25 and 27
14arr.splice(2, 1, 25, 27);
15console.log("After arr.splice(2, 1, 25, 27):", arr);
16
17// Original nums: [ 0, 1, 2, 3, 4 ]
18// Result of nums.slice(1, 4): [ 1, 2, 3 ]
19// nums after slice (unchanged): [ 0, 1, 2, 3, 4 ]
20
21// Original arr: [ 10, 20, 30, 40 ]
22// After arr.splice(2, 1, 25, 27): [ 10, 20, 25, 27, 40 ]
  • ‘slice’ सिर्फ तत्व निकालता है और असली एरे को नहीं बदलता।
  • ‘splice’ तत्व जोड़ता या हटाता है, तथा एरे को बदल देता है—इसलिए इसके प्रभाव को ध्यान से समझें।

इटरशन (for / for...of / forEach)

एरे को अनुक्रम में संसाधित करने के कई तरीके हैं, जिन्हें आप उद्देश्य और अपनी कोडिंग स्टाइल के अनुसार चुन सकते हैं। यहाँ तीन आम प्रकार के लूप दिए गए हैं।

 1const items = ['apple', 'banana', 'cherry'];
 2console.log("Items:", items);
 3
 4// classic for
 5console.log("\n--- Classic for loop ---");
 6for (let i = 0; i < items.length; i++) {
 7  console.log(`Index: ${i}, Value: ${items[i]}`);
 8}
 9
10// for...of (recommended for values)
11console.log("\n--- for...of loop ---");
12for (const item of items) {
13  console.log(`Value: ${item}`);
14}
15
16// forEach (functional style)
17console.log("\n--- forEach loop ---");
18items.forEach((item, index) => {
19  console.log(`Index: ${index}, Value: ${item}`);
20});
  • ‘for’ लूप सबसे लचीला है—यह इंडेक्स से काम करने और ‘break’ जैसे स्टेटमेंट से इटरशन पर सूक्ष्म नियंत्रण देता है।
  • ‘for...of’ तत्वों के मान को सँभालने का आसान तरीका देता है और पढ़ने-समझने में सबसे अच्छा संतुलन रखता है।
  • ‘forEach’ फंक्शनल-शैली के कोड की सुविधा देता है और प्रत्येक तत्व पर लॉगिंग या डेटा अपडेट जैसी साइड-इफेक्ट वाली का कार्यों के लिए उपयुक्त है। लेकिन ध्यान दें कि इसमें ‘break’ या ‘continue’ का प्रयोग नहीं किया जा सकता, और यह ‘await’ के साथ असिंक्रोनस प्रोसेसिंग के लिए उपयुक्त नहीं है

map / filter / reduce — उच्च-क्रम के फ़ंक्शन

map, filter और reduce उच्च स्तरीय फ़ंक्शन हैं जिनका अक्सर एरेज़ को ट्रांसफॉर्म, फिल्टर या एकत्रित करते समय उपयोग किया जाता है। क्योंकि आप दोहराए जाने वाले प्रोसेसिंग को स्पष्ट रूप से व्यक्त कर सकते हैं, आपका कोड सरल और समझने में आसान बन जाता है।

 1const numbers = [1, 2, 3, 4, 5];
 2console.log("Original numbers:", numbers);
 3
 4// map: transform each item
 5const doubled = numbers.map(n => n * 2);
 6console.log("\nResult of map (n * 2):", doubled);
 7
 8// filter: select items
 9const evens = numbers.filter(n => n % 2 === 0);
10console.log("Result of filter (even numbers):", evens);
11
12// reduce: accumulate to single value
13const sum = numbers.reduce((acc, n) => acc + n, 0);
14console.log("Result of reduce (sum):", sum);
15
16// Original numbers: [ 1, 2, 3, 4, 5 ]
17// Result of map (n * 2): [ 2, 4, 6, 8, 10 ]
18// Result of filter (even numbers): [ 2, 4 ]
19// Result of reduce (sum): 15
  • इन विधियों से आप डिक्लेरेटिव शैली में कार्य पर ध्यान केंद्रित कर सकते हैं, जिससे कोड समझने में आसान और अनावश्यक साइड इफेक्ट्स वाले कार्यों से बचा जा सकता है।

find / findIndex / some / every

यहाँ सर्च और कंडीशन-चेकिंग वाले तरीकों का संक्षिप्त परिचय है। ये वो तरीके हैं जो किसी शर्त पर खरे उतरने वाले तत्व खोजने या सेट पर बूलियन चेक लगाने में काम आते हैं।

 1const users = [
 2  { id: 1, name: 'Alice' },
 3  { id: 2, name: 'Bob' },
 4  { id: 3, name: 'Carol' }
 5];
 6
 7console.log("Users:", users);
 8
 9// Find the first user whose name is 'Bob'
10const bob = users.find(user => user.name === 'Bob');
11console.log("\nResult of find (name === 'Bob'):", bob);
12
13// Find index of the user whose id is 3
14const indexOfId3 = users.findIndex(user => user.id === 3);
15console.log("Result of findIndex (id === 3):", indexOfId3);
16
17// Check if there exists a user with id = 2
18const hasId2 = users.some(user => user.id === 2);
19console.log("Result of some (id === 2):", hasId2);
20
21// Check if all users have a numeric id
22const allHaveNumericId = users.every(user => typeof user.id === 'number');
23console.log("Result of every (id is number):", allHaveNumericId);
24// Result of find (name === 'Bob'): { id: 2, name: 'Bob' }
25// Result of findIndex (id === 3): 2
26// Result of some (id === 2): true
27// Result of every (id is number): true
  • ‘find’ वह पहला तत्व लौटाता है जो शर्त को पूरा करता है।
  • ‘findIndex’ उस तत्व का इंडेक्स लौटाता है जो शर्त से मेल खाता है।
  • ‘some’ ‘true’ लौटाता है अगर कम से कम एक तत्व शर्त को पूरा करता है।
  • ‘every’ ‘true’ लौटाता है यदि सभी तत्व शर्त को पूरा करते हैं।

ये सभी एरे की प्रोसेसिंग में बहुत काम आते हैं, और अगर आप इन्हें स्थिति के अनुसार सही ढंग से प्रयोग करें तो कोड संक्षिप्त और स्पष्ट रहेगा।

सॉर्टिंग और तुलना फ़ंक्शन

एरे ‘sort’ से सॉर्ट किया जाता है, लेकिन डिफ़ॉल्ट रूप में यह तत्वों की तुलना स्ट्रिंग्स की तरह करता है, जिससे नंबर सॉर्ट करते समय अजीब परिणाम आ सकते हैं।

 1const nums = [10, 2, 33, 4];
 2console.log("Original nums:", nums);
 3
 4// Default sort: compares elements as strings (not suitable for numbers)
 5nums.sort();
 6console.log("\nAfter default sort (string comparison):", nums);
 7
 8// Numeric ascending sort using a compare function
 9nums.sort((a, b) => a - b);
10console.log("After numeric sort (a - b):", nums);
11
12// Sort objects by a property
13const people = [{ age: 30 }, { age: 20 }, { age: 25 }];
14console.log("\nOriginal people:", people);
15
16people.sort((a, b) => a.age - b.age);
17console.log("After sorting people by age:", people);
18
19// After default sort (string comparison): [ 10, 2, 33, 4 ]
20// After numeric sort (a - b): [ 2, 4, 10, 33 ]
21// Original people: [ { age: 30 }, { age: 20 }, { age: 25 } ]
22// After sorting people by age: [ { age: 20 }, { age: 25 }, { age: 30 } ]
  • नंबर्स या ऑब्जेक्ट्स को सॉर्ट करते समय हमेशा अपनी मनचाही क्रमबद्धता के लिए तुलना फ़ंक्शन जरूर दें।
  • तुलना फ़ंक्शन में, निगेटिव रिटर्न वैल्यू पर ‘a’ ‘b’ से पहले आएगा, पॉजिटिव पर ‘b’ ‘a’ से पहले आएगा और 0 पर दोनों की स्थिति जस की तस रहेगी।

एरे की कॉपी और अपरिवर्तनीयता

एरेज़ की कॉपी बनाते समय, 'reference copy' और 'shallow copy' के बीच का अंतर समझना महत्वपूर्ण है। अगर एरे के अंदर ऑब्जेक्ट्स हों तो ध्‍यान दें कि शैलो कॉपी से वे आंतरिक ऑब्जेक्ट्स साझा रहेंगे।

संदर्भ प्रतिलिपि

जब आप एक एरे को दूसरे वेरिएबल को असाइन करते हैं, तो एरे स्वयं डुप्लिकेट नहीं होती; बल्कि, उसी एरे की ओर इशारा करने वाला 'संदर्भ' कॉपी होता है।

 1const a = [1, 2, 3];
 2console.log("Original a:", a);
 3
 4// Reference copy; modifying b also affects a
 5const b = a;
 6console.log("\nReference copy b = a:", b);
 7// Reference copy b = a: [ 1, 2, 3 ]
 8
 9b[0] = 100;
10console.log("After modifying b[0] = 100:");
11console.log("a:", a);  // a: [ 100, 2, 3 ] (affected)
12console.log("b:", b);  // b: [ 100, 2, 3 ]
  • संदर्भ प्रतिलिपि में, यदि आप कॉपी किए गए वेरिएबल के माध्यम से एरे की सामग्री को संशोधित करते हैं, तो वे परिवर्तन उस मूल वेरिएबल में भी दिखाई देंगे, जो उसी एरे को संदर्भित करता है।

उथली प्रतिलिपि

slice() या स्प्रेड सिंटैक्स का उपयोग करने पर 'उथली प्रतिलिपि' बनती है क्योंकि केवल मान डुप्लिकेट होते हैं; मूल और कॉपी की गई एरेज़ को अलग-अलग इकाइयों के रूप में माना जाता है।

 1const a = [1, 2, 3];
 2console.log("Original a:", a);
 3
 4// Shallow copy (new array)
 5const b = a.slice();
 6console.log("\nShallow copy using slice():", b);
 7// Shallow copy using slice(): [ 100, 2, 3 ]
 8
 9const c = [...a];
10console.log("Shallow copy using spread [...a]:", c);
11// Shallow copy using spread [...a]: [ 100, 2, 3 ]
12
13// Modifying c or d does NOT affect a
14b[1] = 200;
15c[2] = 300;
16console.log("\nAfter modifying b[1] = 200 and c[2] = 300:");
17console.log("a:", a);   // [ 100, 2, 3 ]
18console.log("b:", b);   // [ 100, 200, 3 ]
19console.log("c:", c);   // [ 100, 2, 300 ]
  • यह कोड दर्शाता है कि slice() या स्प्रेड सिंटैक्स द्वारा बनाई गई एरे की उथली प्रतिलिपि मूल एरे को प्रभावित नहीं करती।

उथली प्रतिलिपि और अपरिवर्तनीयता

यदि एरे के अंदर ऑब्जेक्ट्स हों, तो 'उथली प्रतिलिपि' के जरिए एरे को डुप्लिकेट करने पर भी अनचाहा शेयरिंग हो सकता है।

 1// Shallow copy doesn't clone inner objects
 2const nested = [{ x: 1 }, { x: 2 }];
 3console.log("\nOriginal nested:", nested);
 4// Original nested: [ { x: 1 }, { x: 2 } ]
 5
 6const shallow = nested.slice();
 7console.log("Shallow copy of nested:", shallow);
 8// Shallow copy of nested: [ { x: 1 }, { x: 2 } ]
 9
10// Changing inner object affects both arrays
11shallow[0].x = 99;
12console.log("\nAfter shallow[0].x = 99:");
13console.log("nested:", nested);
14console.log("shallow:", shallow);
15// nested: [ { x: 99 }, { x: 2 } ]
16// shallow: [ { x: 99 }, { x: 2 } ]
  • यह कोड दर्शाता है कि उथली प्रतिलिपि में, आंतरिक ऑब्जेक्ट्स साझा किए जाते हैं, इसलिए उन आंतरिक ऑब्जेक्ट्स में बदलाव करने पर वह मूल एरे और प्रतिलिपि दोनों पर प्रभाव डालता है।
  • अगर आपको स्वतंत्र डेटा चाहिए तो आपको ‘structuredClone()’ या JSON कन्वर्शन जैसे तरीके से ‘डीप कॉपी’ का प्रयोग करना होगा।

उपयोगी यूटिलिटी विधियाँ

नीचे दिए गए तरीके वे यूटिलिटी मेथड्स हैं जो एरे के साथ कार्य करते समय अक्सर काम आते हैं। अपनी आवश्यकता के अनुसार इन्हें सही तरह से इस्तेमाल करके आप छोटा और पढ़ने में आसान कोड लिख सकते हैं।

includes

includes विधि यह जांचती है कि कोई विशेष मान एरे में शामिल है या नहीं।

1// includes: check if array contains a value
2const letters = ['a', 'b', 'c'];
3const hasB = letters.includes('b');
4console.log("letters:", letters);  // [ 'a', 'b', 'c' ]
5console.log("letters.includes('b'):", hasB); // true
  • इस कोड में, includes विधि का उपयोग संक्षेप में यह पता लगाने के लिए किया गया है कि एरे में निर्दिष्ट मान मौजूद है या नहीं।

concat

concat विधि एक नई एरे लौटाती है जिसमें निर्दिष्ट एरे या मानों को अंत में जोड़ दिया जाता है, जबकि मूल एरे अपरिवर्तित रहती है।

1// concat: merge arrays without mutation
2const a1 = [1, 2];
3const a2 = [3, 4];
4const combined = a1.concat(a2);
5console.log("a1.concat(a2):", combined); // [ 1, 2, 3, 4 ]
6console.log("a1(unchanged):", a1);       // [ 1, 2 ]
  • यह कोड दिखाता है कि concat विधि गैर-विनाशकारी है, जिससे आप मूल एरे को बनाए रखते हुए एक नई एरे बना सकते हैं।

flat

flat विधि का उपयोग करके, आप नेस्टेड एरेज़ को समतल कर सकते हैं।

1// flat and flatMap: flatten arrays or map + flatten in one step
2const nested = [1, [2, [3]]];
3console.log("nested:", nested); // nested: [ 1, [ 2, [ 3 ] ] ]
4console.log("nested.flat():", nested.flat()); // default depth = 1
5// nested.flat(): [ 1, 2, [ 3 ] ]
  • यह कोड एक स्तर तक एरे को समतल करने के परिणाम को दर्शाता है।
  • flat आपको गहराई निर्दिष्ट करने की अनुमति देता है, इसलिए आप आवश्यकतानुसार नेस्टिंग को लचीलापन पूर्वक हल कर सकते हैं।

flatMap

flatMap विधि प्रत्येक तत्व पर परिवर्तन लागू करती है और फिर परिणाम को स्वचालित रूप से एक-आयामी एरे में समतल कर देती है।

1// flat and flatMap: flatten arrays or map + flatten in one step
2const words = ['hello world', 'hi'];
3console.log("words:", words); // [ 'hello world', 'hi' ]
4
5const splitWords = words.flatMap(w => w.split(' '));
6console.log("words.flatMap(w => w.split(' ')):", splitWords);
7// words.flatMap(w => w.split(' ')): [ 'hello', 'world', 'hi' ]
  • यह कोड एक उदाहरण दिखाता है जिसमें एरे की प्रत्येक स्ट्रिंग को स्पेस द्वारा विभाजित किया गया है, और परिणामों को जोड़कर एकल एरे में समतल किया गया है।

join

join विधि निर्दिष्ट विभाजक के साथ एरे के तत्वों को जोड़कर एक स्ट्रिंग बनाती है।

1// join: combine elements into a string with a separator
2const csv = ['a', 'b', 'c'].join(',');
3console.log("['a', 'b', 'c'].join(','):", csv);  // a,b,c
  • इस कोड में, join विधि का उपयोग एरे को कॉमा-सेपरेटेड स्ट्रिंग में बदलने के लिए किया गया है।

सामान्य गलतियाँ

एरे के ऑपरेशन शुरू में आसान लग सकते हैं, लेकिन इनमें कई बिंदु हैं जहाँ अनजाने में गलत व्यवहार सामने आ सकता है। रोज़मर्रा की एरे प्रोसेसिंग में कई गलतियाँ छिप जाती हैं—इन बिंदुओं को याद रखने से आपके कोड की विश्वसनीयता बढ़ जाएगी।

  • ‘Array’ का ‘sort()’ डिफ़ॉल्ट रूप से स्ट्रिंग तुलना के आधार पर सॉर्ट करता है। नंबर्स को सही से सॉर्ट करने के लिए हमेशा तुलना फंक्शन दें।
  • एरे की कॉपी (जैसे ‘slice’ या स्प्रेड सिंटैक्स के जरिए) करने पर शैलो कॉपी बनती है। अगर आपके एरे में ऑब्जेक्ट्स हैं, तो ध्यान रखें कि असली डेटा अनजाने में बदल सकता है।
  • ‘splice’ एक हानिकारक तरीका है जो एरे को सीधे बदलता है, जबकि ‘slice’ एक गैर-हानिकारक तरीका है जो असली एरे को नहीं बदलता। इनका उपयोग अपनी आवश्यकता अनुसार सही तरीके से करना ज़रूरी है।
  • ‘forEach’ ‘await’ के साथ असिंक्रोनस प्रोसेसिंग वाले लूप्स के लिए उपयुक्त नहीं है। अगर आपको क्रमवार रूप से असिंक्रोनस प्रोसेसिंग करनी हो तो ‘for...of’ का इस्तेमाल करना बेहतर होगा।

व्यावहारिक उदाहरण

नीचे एक उदाहरण दिया है जिसमें एरे मेथड्स को मिलाकर ‘यूजर डेटा से कुल उम्र निकालना, 30 या उससे अधिक उम्र वालों को छाँटना, और नामों की सूची बनाना’ दिखाया गया है।

 1const users = [
 2  { name: 'Alice', age: 28 },
 3  { name: 'Bob', age: 34 },
 4  { name: 'Carol', age: 41 },
 5  { name: 'Dave', age: 19 }
 6];
 7
 8console.log("Users:", users);
 9
10// sum ages
11const totalAge = users.reduce((acc, u) => acc + u.age, 0);
12console.log("\nTotal age of all users:", totalAge);
13// Total age of all users: 122
14
15// filter and map names of users 30 and older
16const namesOver30 = users
17  .filter(u => u.age >= 30)
18  .map(u => u.name);
19
20console.log("Users aged 30 or older (names):", namesOver30);
21// Users aged 30 or older (names): [ 'Bob', 'Carol' ]
  • ‘reduce’, ‘filter’, और ‘map’ को चेन करके आप डेटा को जोड़ने, कंडीशन के अनुसार छाँटने और बदलने का कार्य बहुत सहजता से कर सकते हैं।
  • इस तरह की ‘data processing pipeline’ पढ़ने में आसान होती है, और कम साइड-इफेक्ट वाली शैली के कारण असली दुनिया के ऐप्लिकेशन्स में खूब इस्तेमाल की जाती है।

सारांश

जावास्क्रिप्ट एरे में, मामूली ऑपरेशन भी व्यापक हैं, और उच्च-क्रमीय फंक्शंस से आपका कोड और संक्षिप्त व अभिव्यक्तिपूर्ण बन जाता है। समझने के लिए कई बिंदु हैं, लेकिन जब आप हरेक का सही उपयोग सीख लेंगे तो डेटा प्रोसेसिंग बहुत सुगम हो जाएगी।

आप हमारे YouTube चैनल पर Visual Studio Code का उपयोग करके ऊपर दिए गए लेख के साथ आगे बढ़ सकते हैं। कृपया YouTube चैनल को भी देखें।

YouTube Video