हिन्दी

जावास्क्रिप्ट एरेज़ के साथ फंक्शनल प्रोग्रामिंग की शक्ति को अनलॉक करें। बिल्ट-इन तरीकों का उपयोग करके अपने डेटा को कुशलतापूर्वक ट्रांसफ़ॉर्म, फ़िल्टर और रिड्यूस करना सीखें।

जावास्क्रिप्ट एरेज़ के साथ फंक्शनल प्रोग्रामिंग में महारत हासिल करना

वेब डेवलपमेंट के निरंतर विकसित हो रहे परिदृश्य में, जावास्क्रिप्ट एक आधारशिला बनी हुई है। जबकि ऑब्जेक्ट-ओरिएंटेड और इंपेरेटिव प्रोग्रामिंग पैराडाइम लंबे समय से हावी रहे हैं, फंक्शनल प्रोग्रामिंग (FP) को काफी लोकप्रियता मिल रही है। FP इम्यूटेबिलिटी, प्योर फ़ंक्शंस और डिक्लेरेटिव कोड पर जोर देती है, जिससे अधिक मजबूत, रखरखाव योग्य और पूर्वानुमानित एप्लिकेशन बनते हैं। जावास्क्रिप्ट में फंक्शनल प्रोग्रामिंग को अपनाने का सबसे शक्तिशाली तरीका इसके नेटिव एरे मेथड्स का लाभ उठाना है।

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

फंक्शनल प्रोग्रामिंग क्या है?

जावास्क्रिप्ट एरेज़ में गोता लगाने से पहले, आइए संक्षेप में फंक्शनल प्रोग्रामिंग को परिभाषित करें। इसके मूल में, FP एक प्रोग्रामिंग पैराडाइम है जो गणना को गणितीय फ़ंक्शंस के मूल्यांकन के रूप में मानता है और स्टेट और म्यूटेबल डेटा को बदलने से बचता है। प्रमुख सिद्धांतों में शामिल हैं:

इन सिद्धांतों को अपनाने से ऐसा कोड बन सकता है जिसे समझना, टेस्ट करना और डीबग करना आसान होता है, खासकर जटिल एप्लिकेशन्स में। जावास्क्रिप्ट के एरे मेथड्स इन कॉन्सेप्ट्स को लागू करने के लिए पूरी तरह से उपयुक्त हैं।

जावास्क्रिप्ट एरे मेथड्स की शक्ति

जावास्क्रिप्ट एरेज़ बिल्ट-इन मेथड्स के एक समृद्ध सेट से लैस हैं जो पारंपरिक लूप्स (जैसे for या while) का सहारा लिए बिना परिष्कृत डेटा मैनिपुलेशन की अनुमति देते हैं। ये मेथड्स अक्सर नए एरेज़ लौटाते हैं, इम्यूटेबिलिटी को बढ़ावा देते हैं, और कॉलबैक फ़ंक्शंस को स्वीकार करते हैं, जिससे एक फंक्शनल दृष्टिकोण सक्षम होता है।

आइए सबसे मौलिक फंक्शनल एरे मेथड्स का पता लगाएं:

1. Array.prototype.map()

map() मेथड एक नया एरे बनाता है जो दिए गए फ़ंक्शन को कॉलिंग एरे के हर एलिमेंट पर कॉल करने के परिणामों से भरा होता है। यह एक एरे के प्रत्येक एलिमेंट को कुछ नया बनाने के लिए आदर्श है।

सिंटैक्स:

array.map(callback(currentValue[, index[, array]])[, thisArg])

मुख्य विशेषताएँ:

उदाहरण: प्रत्येक संख्या को दोगुना करना

कल्पना कीजिए कि आपके पास संख्याओं का एक एरे है और आप एक नया एरे बनाना चाहते हैं जहाँ प्रत्येक संख्या दोगुनी हो।

const numbers = [1, 2, 3, 4, 5];

// ट्रांसफॉर्मेशन के लिए map का उपयोग करना
const doubledNumbers = numbers.map(number => number * 2);

console.log(numbers); // आउटपुट: [1, 2, 3, 4, 5] (मूल एरे अपरिवर्तित है)
console.log(doubledNumbers); // आउटपुट: [2, 4, 6, 8, 10]

उदाहरण: ऑब्जेक्ट्स से प्रॉपर्टीज़ निकालना

एक सामान्य उपयोग का मामला ऑब्जेक्ट्स के एरे से विशिष्ट प्रॉपर्टीज़ निकालना है। मान लीजिए कि हमारे पास उपयोगकर्ताओं की एक सूची है और हम केवल उनके नाम प्राप्त करना चाहते हैं।

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];

const userNames = users.map(user => user.name);

console.log(userNames); // आउटपुट: ['Alice', 'Bob', 'Charlie']

2. Array.prototype.filter()

filter() मेथड एक नया एरे बनाता है जिसमें वे सभी एलिमेंट होते हैं जो दिए गए फ़ंक्शन द्वारा लागू किए गए टेस्ट को पास करते हैं। इसका उपयोग एक शर्त के आधार पर एलिमेंट्स का चयन करने के लिए किया जाता है।

सिंटैक्स:

array.filter(callback(element[, index[, array]])[, thisArg])

मुख्य विशेषताएँ:

उदाहरण: सम संख्याओं को फ़िल्टर करना

आइए संख्याओं के एरे को फ़िल्टर करें ताकि केवल सम संख्याएँ रखी जा सकें।

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// सम संख्याओं का चयन करने के लिए filter का उपयोग करना
const evenNumbers = numbers.filter(number => number % 2 === 0);

console.log(numbers); // आउटपुट: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(evenNumbers); // आउटपुट: [2, 4, 6, 8, 10]

उदाहरण: सक्रिय उपयोगकर्ताओं को फ़िल्टर करना

हमारे उपयोगकर्ताओं के एरे से, आइए उन उपयोगकर्ताओं को फ़िल्टर करें जो सक्रिय के रूप में चिह्नित हैं।

const users = [
  { id: 1, name: 'Alice', isActive: true },
  { id: 2, name: 'Bob', isActive: false },
  { id: 3, name: 'Charlie', isActive: true },
  { id: 4, name: 'David', isActive: false }
];

const activeUsers = users.filter(user => user.isActive);

console.log(activeUsers); 
/* आउटपुट:
[
  { id: 1, name: 'Alice', isActive: true },
  { id: 3, name: 'Charlie', isActive: true }
]
*/

3. Array.prototype.reduce()

reduce() मेथड एरे के प्रत्येक एलिमेंट पर एक उपयोगकर्ता-प्रदत्त "रिड्यूसर" कॉलबैक फ़ंक्शन निष्पादित करता है, क्रम में, पिछले एलिमेंट पर गणना से वापसी मान में पास करता है। एरे के सभी एलिमेंट्स पर रिड्यूसर चलाने का अंतिम परिणाम एक एकल मान होता है।

यह यकीनन एरे मेथड्स में सबसे बहुमुखी है और कई फंक्शनल प्रोग्रामिंग पैटर्न की आधारशिला है, जो आपको एक एरे को एक एकल मान (जैसे, योग, उत्पाद, गणना, या यहां तक कि एक नया ऑब्जेक्ट या एरे) तक "रिड्यूस" करने की अनुमति देता है।

सिंटैक्स:

array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

मुख्य विशेषताएँ:

उदाहरण: संख्याओं का योग करना

आइए हमारे एरे में सभी संख्याओं का योग करें।

const numbers = [1, 2, 3, 4, 5];

// संख्याओं का योग करने के लिए reduce का उपयोग करना
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0); // 0 initialValue है

console.log(sum); // आउटपुट: 15

स्पष्टीकरण:

उदाहरण: एक प्रॉपर्टी द्वारा ऑब्जेक्ट्स को समूहित करना

हम reduce का उपयोग ऑब्जेक्ट्स के एरे को एक ऑब्जेक्ट में बदलने के लिए कर सकते हैं जहाँ मानों को एक विशिष्ट प्रॉपर्टी द्वारा समूहित किया जाता है। आइए अपने उपयोगकर्ताओं को उनके `isActive` स्टेटस के आधार पर समूहित करें।

const users = [
  { id: 1, name: 'Alice', isActive: true },
  { id: 2, name: 'Bob', isActive: false },
  { id: 3, name: 'Charlie', isActive: true },
  { id: 4, name: 'David', isActive: false }
];

const groupedUsers = users.reduce((acc, user) => {
  const status = user.isActive ? 'active' : 'inactive';
  if (!acc[status]) {
    acc[status] = [];
  }
  acc[status].push(user);
  return acc;
}, {}); // खाली ऑब्जेक्ट {} initialValue है

console.log(groupedUsers);
/* आउटपुट:
{
  active: [
    { id: 1, name: 'Alice', isActive: true },
    { id: 3, name: 'Charlie', isActive: true }
  ],
  inactive: [
    { id: 2, name: 'Bob', isActive: false },
    { id: 4, name: 'David', isActive: false }
  ]
}
*/

उदाहरण: घटनाओं की गिनती

आइए एक सूची में प्रत्येक फल की आवृत्ति की गणना करें।

const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];

const fruitCounts = fruits.reduce((acc, fruit) => {
  acc[fruit] = (acc[fruit] || 0) + 1;
  return acc;
}, {});

console.log(fruitCounts); // आउटपुट: { apple: 3, banana: 2, orange: 1 }

4. Array.prototype.forEach()

जबकि forEach() एक नया एरे नहीं लौटाता है और इसे अक्सर अधिक इंपेरेटिव माना जाता है क्योंकि इसका प्राथमिक उद्देश्य प्रत्येक एरे एलिमेंट के लिए एक फ़ंक्शन निष्पादित करना है, यह अभी भी एक मौलिक मेथड है जो फंक्शनल पैटर्न में एक भूमिका निभाता है, खासकर जब साइड इफेक्ट आवश्यक होते हैं या जब एक ट्रांसफ़ॉर्म्ड आउटपुट की आवश्यकता के बिना पुनरावृति की जाती है।

सिंटैक्स:

array.forEach(callback(element[, index[, array]])[, thisArg])

मुख्य विशेषताएँ:

उदाहरण: प्रत्येक एलिमेंट को लॉग करना

const messages = ['Hello', 'Functional', 'World'];

messages.forEach(message => console.log(message));
// आउटपुट:
// Hello
// Functional
// World

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

5. Array.prototype.find() और Array.prototype.findIndex()

ये मेथड्स एक एरे में विशिष्ट एलिमेंट्स का पता लगाने के लिए उपयोगी हैं।

उदाहरण: एक उपयोगकर्ता को खोजना

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];

const bob = users.find(user => user.name === 'Bob');
const bobIndex = users.findIndex(user => user.name === 'Bob');
const nonExistentUser = users.find(user => user.name === 'David');
const nonExistentIndex = users.findIndex(user => user.name === 'David');

console.log(bob); // आउटपुट: { id: 2, name: 'Bob' }
console.log(bobIndex); // आउटपुट: 1
console.log(nonExistentUser); // आउटपुट: undefined
console.log(nonExistentIndex); // आउटपुट: -1

6. Array.prototype.some() और Array.prototype.every()

ये मेथड्स यह परीक्षण करते हैं कि क्या एरे में सभी एलिमेंट प्रदान किए गए फ़ंक्शन द्वारा लागू किए गए परीक्षण को पास करते हैं।

उदाहरण: उपयोगकर्ता की स्थिति की जाँच करना

const users = [
  { id: 1, name: 'Alice', isActive: true },
  { id: 2, name: 'Bob', isActive: false },
  { id: 3, name: 'Charlie', isActive: true }
];

const hasInactiveUser = users.some(user => !user.isActive);
const allAreActive = users.every(user => user.isActive);

console.log(hasInactiveUser); // आउटपुट: true (क्योंकि बॉब निष्क्रिय है)
console.log(allAreActive); // आउटपुट: false (क्योंकि बॉब निष्क्रिय है)

const allUsersActive = users.filter(user => user.isActive).length === users.length;
console.log(allUsersActive); // आउटपुट: false

// सीधे every का उपयोग करके विकल्प
const allUsersActiveDirect = users.every(user => user.isActive);
console.log(allUsersActiveDirect); // आउटपुट: false

जटिल परिचालनों के लिए एरे मेथड्स को श्रृंखलित करना

जावास्क्रिप्ट एरेज़ के साथ फंक्शनल प्रोग्रामिंग की असली शक्ति तब चमकती है जब आप इन मेथड्स को एक साथ श्रृंखलित करते हैं। क्योंकि इनमें से अधिकांश मेथड्स नए एरेज़ लौटाते हैं (forEach को छोड़कर), आप एक मेथड के आउटपुट को दूसरे के इनपुट में निर्बाध रूप से पाइप कर सकते हैं, जिससे सुरुचिपूर्ण और पठनीय डेटा पाइपलाइन बनती हैं।

उदाहरण: सक्रिय उपयोगकर्ता नाम खोजना और उनके आईडी को दोगुना करना

आइए सभी सक्रिय उपयोगकर्ताओं को खोजें, उनके नाम निकालें, और फिर एक नया एरे बनाएं जहां प्रत्येक नाम के पहले एक संख्या हो जो *फ़िल्टर की गई* सूची में उसके इंडेक्स का प्रतिनिधित्व करती हो, और उनकी आईडी दोगुनी हो।

const users = [
  { id: 1, name: 'Alice', isActive: true },
  { id: 2, name: 'Bob', isActive: false },
  { id: 3, name: 'Charlie', isActive: true },
  { id: 4, name: 'David', isActive: true },
  { id: 5, name: 'Eve', isActive: false }
];

const processedActiveUsers = users
  .filter(user => user.isActive) // केवल सक्रिय उपयोगकर्ता प्राप्त करें
  .map((user, index) => ({      // प्रत्येक सक्रिय उपयोगकर्ता को ट्रांसफ़ॉर्म करें
    name: `${index + 1}. ${user.name}`,
    doubledId: user.id * 2
  }));

console.log(processedActiveUsers);
/* आउटपुट:
[
  { name: '1. Alice', doubledId: 2 },
  { name: '2. Charlie', doubledId: 6 },
  { name: '3. David', doubledId: 8 }
]
*/

यह श्रृंखलित दृष्टिकोण डिक्लेरेटिव है: हम स्पष्ट लूप प्रबंधन के बिना चरणों (फ़िल्टर, फिर मैप) को निर्दिष्ट करते हैं। यह इम्यूटेबल भी है, क्योंकि प्रत्येक चरण एक नया एरे या ऑब्जेक्ट उत्पन्न करता है, जिससे मूल users एरे अछूता रहता है।

अभ्यास में इम्यूटेबिलिटी

फंक्शनल प्रोग्रामिंग काफी हद तक इम्यूटेबिलिटी पर निर्भर करती है। इसका मतलब है कि मौजूदा डेटा संरचनाओं को संशोधित करने के बजाय, आप वांछित परिवर्तनों के साथ नई संरचनाएं बनाते हैं। जावास्क्रिप्ट के एरे मेथड्स जैसे map, filter, और slice नए एरेज़ लौटाकर स्वाभाविक रूप से इसका समर्थन करते हैं।

इम्यूटेबिलिटी क्यों महत्वपूर्ण है?

जब आपको एक ऐसा ऑपरेशन करने की आवश्यकता होती है जो पारंपरिक रूप से एक एरे को म्यूटेट करेगा (जैसे एक एलिमेंट जोड़ना या हटाना), तो आप slice, स्प्रेड सिंटैक्स (...), या अन्य फंक्शनल मेथड्स के संयोजन का उपयोग करके इम्यूटेबिलिटी प्राप्त कर सकते हैं।

उदाहरण: एक एलिमेंट को इम्यूटेबल रूप से जोड़ना

const originalArray = [1, 2, 3];

// इंपेरेटिव तरीका (originalArray को म्यूटेट करता है)
// originalArray.push(4);

// स्प्रेड सिंटैक्स का उपयोग करके फंक्शनल तरीका
const newArrayWithPush = [...originalArray, 4];
console.log(originalArray); // आउटपुट: [1, 2, 3]
console.log(newArrayWithPush); // आउटपुट: [1, 2, 3, 4]

// स्लाइस और कॉन्केटिनेशन का उपयोग करके फंक्शनल तरीका (अब कम आम है)
const newArrayWithSlice = originalArray.slice(0, originalArray.length).concat(4);
console.log(newArrayWithSlice); // आउटपुट: [1, 2, 3, 4]

उदाहरण: एक एलिमेंट को इम्यूटेबल रूप से हटाना

const originalArray = [1, 2, 3, 4, 5];

// इंडेक्स 2 पर एलिमेंट हटाएं (मान 3)

// स्लाइस और स्प्रेड सिंटैक्स का उपयोग करके फंक्शनल तरीका
const newArrayAfterSplice = [
  ...originalArray.slice(0, 2),
  ...originalArray.slice(3)
];
console.log(originalArray); // आउटपुट: [1, 2, 3, 4, 5]
console.log(newArrayAfterSplice); // आउटपुट: [1, 2, 4, 5]

// एक विशिष्ट मान को हटाने के लिए फ़िल्टर का उपयोग करना
const newValueToRemove = 3;
const arrayWithoutValue = originalArray.filter(item => item !== newValueToRemove);
console.log(arrayWithoutValue); // आउटपुट: [1, 2, 4, 5]

सर्वश्रेष्ठ अभ्यास और उन्नत तकनीकें

जैसे-जैसे आप फंक्शनल एरे मेथड्स के साथ अधिक सहज होते जाते हैं, इन प्रथाओं पर विचार करें:

उदाहरण: डेटा एकत्रीकरण के लिए फंक्शनल दृष्टिकोण

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

const salesData = [
  { region: 'North', amount: 100 },
  { region: 'South', amount: 150 },
  { region: 'North', amount: 120 },
  { region: 'East', amount: 200 },
  { region: 'South', amount: 180 },
  { region: 'North', amount: 90 }
];

// 1. reduce का उपयोग करके प्रति क्षेत्र कुल बिक्री की गणना करें
const salesByRegion = salesData.reduce((acc, sale) => {
  acc[sale.region] = (acc[sale.region] || 0) + sale.amount;
  return acc;
}, {});

// salesByRegion होगा: { North: 310, South: 330, East: 200 }

// 2. आगे की प्रक्रिया के लिए एकत्रित ऑब्जेक्ट को ऑब्जेक्ट्स के एरे में बदलें
const salesArray = Object.keys(salesByRegion).map(region => ({
  region: region,
  totalAmount: salesByRegion[region]
}));

// salesArray होगा: [
//   { region: 'North', totalAmount: 310 },
//   { region: 'South', totalAmount: 330 },
//   { region: 'East', totalAmount: 200 }
// ]

// 3. reduce का उपयोग करके उच्चतम बिक्री वाले क्षेत्र को खोजें
const highestSalesRegion = salesArray.reduce((max, current) => {
  return current.totalAmount > max.totalAmount ? current : max;
}, { region: '', totalAmount: -Infinity }); // बहुत छोटी संख्या के साथ प्रारंभ करें

console.log('क्षेत्र के अनुसार बिक्री:', salesByRegion);
console.log('बिक्री एरे:', salesArray);
console.log('उच्चतम बिक्री वाला क्षेत्र:', highestSalesRegion);

/*
आउटपुट:
क्षेत्र के अनुसार बिक्री: { North: 310, South: 330, East: 200 }
बिक्री एरे: [
  { region: 'North', totalAmount: 310 },
  { region: 'South', totalAmount: 330 },
  { region: 'East', totalAmount: 200 }
]
उच्चतम बिक्री वाला क्षेत्र: { region: 'South', totalAmount: 330 }
*/

निष्कर्ष

जावास्क्रिप्ट एरेज़ के साथ फंक्शनल प्रोग्रामिंग केवल एक शैलीगत पसंद नहीं है; यह स्वच्छ, अधिक पूर्वानुमानित और अधिक मजबूत कोड लिखने का एक शक्तिशाली तरीका है। map, filter, और reduce जैसे मेथड्स को अपनाकर, आप अपने डेटा को प्रभावी ढंग से ट्रांसफ़ॉर्म, क्वेरी और एकत्र कर सकते हैं, जबकि फंक्शनल प्रोग्रामिंग के मूल सिद्धांतों, विशेष रूप से इम्यूटेबिलिटी और प्योर फ़ंक्शंस का पालन करते हैं।

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