ट्रैक
/
Odin
Odin
/
अभ्यास
/
ऐरे ऑपरेशन
ऐरे ऑपरेशन

ऐरे ऑपरेशन

मध्यम

निर्देश

ऐरे के बुनियादी ऑपरेशन लागू कीजिए।

फंक्शनल भाषाओं में length, map और reduce जैसे ऐरे ऑपरेशन बहुत आम हैं। पहले से मौजूद फंक्शन इस्तेमाल किए बिना बुनियादी ऐरे ऑपरेशनों की एक श्रृंखला लागू कीजिए।

लागू किए जाने वाले ऑपरेशनों की सही संख्या और नाम इस बात पर निर्भर करते हैं कि आप किस ट्रैक पर हैं, ताकि मौजूदा नामों से टकराव न हो। आम तौर पर आपको जो ऑपरेशन लागू करने होंगे, उनमें ये शामिल हैं:

  • append (दो ऐरे दिए जाने पर, दूसरे ऐरे के सारे एलिमेंट पहले ऐरे के अंत में जोड़िए);
  • concatenate (ऐरों की एक श्रृंखला दिए जाने पर, सभी ऐरों के सारे एलिमेंट मिलाकर एक ही समतल ऐरे बनाइए);
  • filter (एक प्रेडिकेट और एक ऐरे दिए जाने पर, वे सारे एलिमेंट वाला ऐरे लौटाइए जिनके लिए predicate(item) सही होता है);
  • length (एक ऐरे दिए जाने पर, उसमें मौजूद कुल एलिमेंट की संख्या लौटाइए);
  • map (एक फंक्शन और एक ऐरे दिए जाने पर, हर एलिमेंट पर function(item) लागू करने के नतीजों वाला ऐरे लौटाइए);
  • foldl (एक फंक्शन, एक ऐरे और शुरुआती एक्युमुलेटर दिए जाने पर, हर एलिमेंट को बाईं ओर से एक्युमुलेटर में फोल्ड (रिड्यूस) कीजिए);
  • foldr (एक फंक्शन, एक ऐरे और एक शुरुआती एक्युमुलेटर दिए जाने पर, हर एलिमेंट को दाईं ओर से एक्युमुलेटर में फोल्ड (रिड्यूस) कीजिए);
  • reverse (एक ऐरे दिए जाने पर, एक ऐसा ऐरे लौटाइए जिसमें सारे मूल एलिमेंट हों, लेकिन उलटे क्रम में)।

ध्यान रखिए कि फोल्ड फंक्शनों (foldl, foldr) को आर्गुमेंट किस क्रम में दिए जाते हैं, यह महत्वपूर्ण है।

कार्यान्वयन

इस अभ्यास के लिए आपको Odin के पैरामीटर पॉलीमॉर्फिज़्म का उपयोग करना होगा, जिसे आम तौर पर जेनेरिक्स कहा जाता है। अगर आपने यह सुविधा पहले नहीं देखी है, तो शुरुआत करने के लिए यहाँ एक संक्षिप्त परिचय दिया गया है।

पैरामीटर पॉलीमॉर्फिज़्म प्रोग्रामिंग भाषा की एक सुविधा है जो प्रोग्रामरों को अपने कोड में इस्तेमाल होने वाले टाइपों के बारे में कम स्पष्ट रहने देती है (यानी ज़्यादा जेनेरिक, इसीलिए यह नाम), और फिर भी टाइप सेफ्टी बनी रहती है। जाहिर है, यह बात सिर्फ Odin जैसी उन भाषाओं के लिए मायने रखती है जिनमें टाइप की जाँच कड़ी होती है।

चलिए एक उदाहरण से शुरू करते हैं। मान लीजिए आप एक ऐरे के सारे एलिमेंट को एक तय वैल्यू से बढ़ाना चाहते हैं। समस्या काफी आसान है।

incr_array_int :: proc(a: []int, by: int) -> []int {

    new_array := make([]int, len(a))
    for i := 0; i < len(a); i+= 1 {
        new_array[i] = a[i] + by
    }
    return new_array
}

अब मान लीजिए आपको यही काम दशमलव संख्याओं के लिए भी चाहिए?

incr_array_f64 :: proc(a: []f64, by: f64) -> []f64 {

    new_array := make([]f64, len(a))
    for i := 0; i < len(a); i+= 1 {
        new_array[i] = a[i] + by
    }
    return new_array
}

और फिर बिना चिह्न वाले पूर्णांकों, 32-बिट दशमलव संख्याओं, और इसी तरह के और टाइपों के लिए?

थोड़ी ही देर में आपके पास ऐसे बहुत सारे प्रोसीजर हो जाते हैं जो बिल्कुल एक ही काम करते हैं, बस अलग-अलग टाइप के लिए। अगर कभी आपको इनका लॉजिक बदलना पड़े, तो आपको यह पक्का करना होगा कि बदलाव हर वेरिएंट में हो जाए। इसमें बहुत सारा मेंटेनेंस का काम लग सकता है। दूसरी परेशानी यह है कि हर प्रोसीजर को अलग नाम देना पड़ता है, क्योंकि Odin इम्प्लिसिट प्रोसीजर ओवरलोडिंग का समर्थन नहीं करता (एक्सप्लिसिट ओवरलोडिंग का इस्तेमाल तो आप कर सकते हैं, लेकिन वह किसी और अभ्यास की बात है)।

Odin एक व्यावहारिक भाषा है, और यह पैरामीटर पॉलीमॉर्फिज़्म के ज़रिए इसका हल देती है। जब तक कंपाइलर कंपाइल के समय किसी पैरामीटर का टाइप पहचान सके, आप उसे T जैसा कोई जेनेरिक नाम दे सकते हैं। चलिए ऊपर वाले प्रोसीजर को फिर से लिखते हैं:

incr_array :: proc(a: []$T, by: T) -> []T {

    new_array := make([]T, len(a))
    for i := 0; i < len(a); i+= 1 {
        new_array[i] = a[i] + by
    }
    return new_array
}

ध्यान दीजिए कि हमने सारे टाइप एनोटेशन (int या f64) की जगह T लिख दिया है, और T जहाँ पहली बार आता है उससे पहले डॉलर का चिह्न ($T) लगा है। $T टाइप Odin कंपाइलर को बताता है कि नाम T किसी टाइप का जेनेरिक नाम है, जिसे कंपाइल के दौरान असली नाम से बदल दिया जाएगा। और चूँकि अब कंपाइलर को जेनेरिक टाइप T की जानकारी है, इसलिए उसी टाइप की आगे आने वाली जगहों पर सिर्फ चुना हुआ टाइप नाम (T) लिखना काफी है।

अब आप ऐसा कोड लिख सकते हैं:

a_int := incr_array([]int{1, 2, 3}, 10)
a_f64 := incr_array([]f64{1.0, 2.0, 3.0}, 10.0)

पहले स्टेटमेंट में Odin कंपाइलर पहले पैरामीटर का टाइप ([]int) जेनेरिक पैरामीटर के टाइप ([]$T) से मिलाएगा, यह निष्कर्ष निकालेगा कि T = int है, और फिर एक ऐसा वर्शन कंपाइल करेगा जिसमें आगे आने वाले सारे T की जगह int होगा (यानी ऊपर दिए गए int के लिए बने वर्शन incr_array_int() के बराबर)। अगर आप पहले पैरामीटर की परिभाषा में डॉलर का चिह्न छोड़ दें, तो कंपाइलर मौजूदा पैकेज में और इम्पोर्ट की सूची में T नाम का कोई टाइप ढूँढता, और बहुत संभव है कि वह कंपाइल एरर देता: Error: Undeclared name: T.

दूसरा स्टेटमेंट भी बिल्कुल पहले की तरह ही काम करता है, बस इसमें कंपाइलर T को f64 पहचानता है।

जेनेरिक टाइपों को एक अक्षर का नाम देना आम बात है (T और E अक्सर इस्तेमाल होते हैं)।

अब आप पैरामीटर पॉलीमॉर्फिज़्म, यानी जेनेरिक टाइपों, के बारे में इतना जान चुके होंगे कि आप List Operations अभ्यास शुरू कर सकें।

GitHub के ज़रिए संपादित करें यह लिंक एक नई विंडो या टैब में खुलता है
Odin Exercism

ऐरे ऑपरेशन शुरू करने के लिए तैयार हैं?

Exercism पर साइन अप कीजिए और Odin को 73 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।

ऐरे ऑपरेशन को गहराई से जानिए!

रिकर्शन का एक व्यावहारिक परिचय पाइए, ऐरे ऑपरेशन के इम्पेरेटिव और फंक्शनल विकल्प जानिए, और टेल-कॉल रिकर्शन तथा एक्युमुलेटर फंक्शनों की गहराई में उतरिए।