ट्रैक
/
Swift
Swift
/
अभ्यास
/
Double-Null0111: क्लोज़र हमेशा के लिए
Double-Null0111: क्लोज़र हमेशा के लिए

Double-Null0111: क्लोज़र हमेशा के लिए

सीखने का अभ्यास

परिचय

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

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

हालाँकि Swift में फंक्शन तकनीकी रूप से क्लोज़र ही हैं, लेकिन जब लोग Swift में "क्लोज़र" कहते हैं, तो उनका मतलब closure expressions होता है। क्लोज़र एक्सप्रेशन इस तरह लिखे जाते हैं: पहले पैरामीटर की सूची, उसके बाद रिटर्न टाइप, फिर in कीवर्ड, और उसके बाद क्लोज़र की बॉडी, और यह सब घुंघराले ब्रैकेट के एक जोड़े के अंदर रहता है:

{ (a: Double, b: Double) -> Double in
  return (a + b) / 2.0
}

यह (Double, Double) -> Double टाइप का एक क्लोज़र एक्सप्रेशन बनाता है, और इसे इस टाइप के फंक्शन की तरह ही चलाया जा सकता है, यानी इसे सही टाइप के पैरामीटर देकर:

{ (a: Double, b: Double) -> Double in
  return (a + b) / 2.0
}(10.0, 15.0)
// returns 12.5

हर बार चलाने के लिए पूरा क्लोज़र एक्सप्रेशन लिखना बहुत सुविधाजनक नहीं होता, इसलिए क्लोज़र को Swift की किसी भी दूसरी वैल्यू की तरह नामों में असाइन किया जा सकता है। फिर उस नाम को पैरामीटर के साथ लिखकर उसे कॉल किया जा सकता है:

let mean = { (a: Double, b: Double) -> Double in
  (a + b) / 2.0
}

mean(13.0, 100.0)
// returns 56.5

जैसा ऊपर दिखा, क्लोज़र भी आम फंक्शन की तरह return कीवर्ड छोड़ सकते हैं, अगर क्लोज़र की बॉडी एक ही एक्सप्रेशन हो।

अक्सर क्लोज़र हायर-ऑर्डर फंक्शन के साथ इस्तेमाल होते हैं, या तो पैरामीटर के रूप में दिए जाते हैं या परिणाम के रूप में लौटाए जाते हैं:

[11, 75, 3, 99, 53].contains(where: { (x: Int) -> Bool in x > 100 })
// returns false

["apple", "ball", "carrot"].sorted(by: { (s1: String, s2: String) -> Bool in s1.count < s2.count })
// returns ["ball", "apple", "carrot"]

func makeAdder(base: Int) -> (Int) -> Int {
  { (x: Int) -> Int in base + x }
}

निर्देश

एक बार फिर नमस्ते, एजेंट डबल-नल0111।

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

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

आपका काम यह कोड लिखना है जिसकी मदद से आप बॉल में लगे बदबूदार बम को फूटने से पहले निष्क्रिय कर सकें।

1. दो तारों की अदला-बदली के लिए क्लोजर लिखिए

हर बदबूदार बम पर अलग-अलग रंग के तीन तार होते हैं। एक क्लोजर लिखिए जो (String, String, String) ट्यूपल लेता है और उस ट्यूपल को लौटाता है जिसमें पहले दो एलिमेंट का क्रम आपस में बदल दिया गया हो। इस क्लोजर को flip नाम दीजिए।

यह ध्यान रखना ज़रूरी है कि टाइप ChangeClosure होना चाहिए (या कोई sendable टाइप); टाइप की परिभाषा स्टब फाइल में दी गई है। वरना कोड कंपाइल नहीं होगा।

flip(("red", "yellow", "blue"))
// Returns ("yellow", "red", "blue")

2. तारों को घुमाने के लिए क्लोजर लिखिए

एक क्लोजर लिखिए जो (String, String, String) ट्यूपल लेता है और उस ट्यूपल को लौटाता है जिसमें तारों का क्रम बाईं ओर घुमा दिया गया हो। इस क्लोजर को rotate नाम दीजिए।

यह ध्यान रखना ज़रूरी है कि टाइप ChangeClosure होना चाहिए (या कोई sendable टाइप); टाइप की परिभाषा स्टब फाइल में दी गई है।

rotate(("red", "yellow", "blue"))
// Returns ("yellow", "blue", "red")

3. तारों के शफल का जनरेटर बनाइए

बदबूदार बम के तार किस क्रम में काटने हैं, यह पता लगाने के लिए आपको एक ऐसा फंक्शन बनाना होगा जो बम के ID नंबर के आधार पर सही शफल करने वाला फंक्शन तैयार करे।

यह फंक्शन बनाइए:

makeShuffle(
  flipper: @escaping ((String, String, String)) -> (String, String, String),
  rotator: @escaping ((String, String, String)) -> (String, String, String)
) -> ([UInt8], (String, String, String)) -> (String, String, String)

यह फंक्शन इनपुट में दो तारों की अदला-बदली करने वाला एक क्लोजर और तीनों तारों को घुमाने वाला एक क्लोजर लेता है, और एक क्लोजर लौटाता है। जो क्लोजर लौटता है, वह बदबूदार बम का ID नंबर और तीनों तारों का क्रम लेता है, और फिर यह पता लगाता है कि तार किस क्रम में काटने हैं। ID नंबर आठ बिट का बना होता है, और हर बिट यह तय करता है कि तारों की अदला-बदली करनी है या उन्हें घुमाना है।

ID नंबर की हर बिट के लिए, सबसे दाईं बिट से शुरू करते हुए, अगर बिट 0 है तो तारों के ट्यूपल पर flipper क्लोजर लगाइए, और अगर बिट 1 है तो rotator क्लोजर लगाइए। इससे तारों की नई स्थिति मिलती है। ID की आठों बिट पर सही क्लोजर लगाने के बाद, तारों की अंतिम स्थिति से ही यह तय होता है कि उन्हें किस क्रम में काटना है।

let shuffler = makeShuffle(flipper: flip, rotator: rotate)
// Returns ([UInt8], (String, String, String)) -> (String, String, String)
shuffler([1, 0, 0, 1, 1, 0, 1, 1], ("red", "yellow", "blue"))
// Returns ("red", "blue", "yellow")
GitHub के ज़रिए संपादित करें यह लिंक एक नई विंडो या टैब में खुलता है
Swift Exercism

Double-Null0111: क्लोज़र हमेशा के लिए शुरू करने के लिए तैयार हैं?

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