Swift में ऐरे का विलय: + से copy-on-write तक

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Swift में ऐरे कैसे मर्ज करें? उदाहरणों और प्रदर्शन रहस्यों के साथ पूर्ण विश्लेषण

\n\n

यदि आपने कभी Swift में लिखा है, तो आपने निश्चित रूप से इस कार्य का सामना किया होगा: "मेरे पास दो ऐरे हैं, उनमें से एक कैसे बनाऊं?" प्रश्न सरल लगता है, लेकिन इसके पीछे ऑप्टिमाइज़ेशन और बारीकियों की एक पूरी दुनिया छिपी है। Stack Overflow पर इस प्रश्न ने हजारों व्यूज़ प्राप्त किए हैं - और यह व्यर्थ नहीं है। आज हम केवल कोड लिखने का तरीका नहीं दिखाएंगे, बल्कि कंपाइलर के हुड के नीचे झांकेंगे और जानेंगे कि जब आप array1 + array2 लिखते हैं तो वास्तव में क्या होता है। चलिए शुरू करते हैं!

\n\n

सबसे स्पष्ट तरीका: + ऑपरेटर

\n\n

आइए क्लासिक से शुरू करें। Swift में, ऐरे को संख्याओं की तरह जोड़ा जा सकता है:

\n\n
let first = [1, 2, 3]\nlet second = [4, 5, 6]\nlet result = first + second\nprint(result) // [1, 2, 3, 4, 5, 6]
\n\n

सुंदर? हाँ। तेज़? हमेशा नहीं। जब आप + का उपयोग करते हैं, Swift एक नया ऐरे बनाता है और दोनों मूल ऐरे के तत्वों को उसमें कॉपी करता है। यदि आपके ऐरे बड़े हैं (मान लीजिए, प्रत्येक में 100,000 तत्व), तो यह प्रोसेसर के लिए दोगुना काम है। लेकिन रुकिए - एक बारीकी है जिसे copy-on-write (COW) कहा जाता है।

\n\n

Copy-on-Write का जादू: Swift मेमोरी कैसे बचाता है

\n\n

Swift एक स्मार्ट भाषा है। जब आप एक ऐरे को दूसरे को असाइन करते हैं, तो यह तुरंत डेटा कॉपी नहीं करता:

\n\n
var a = [1, 2, 3]\nvar b = a // जब तक डेटा नहीं बदला जाता, a और b एक ही मेमोरी क्षेत्र को संदर्भित करते हैं\nb.append(4) // यहाँ वास्तविक कॉपी होती है: b को अपनी प्रतिलिपि मिलती है
\n\n

इसे copy-on-write कहा जाता है। लेकिन + के माध्यम से विलय करते समय यह काम नहीं करता - परिणाम हमेशा एक नया ऐरे होता है। क्यों? क्योंकि हम केवल पुराने डेटा को संदर्भित नहीं कर रहे हैं, बल्कि दो अलग-अलग स्रोतों के तत्वों से एक नया संग्रह बना रहे हैं। कंपाइलर गारंटी नहीं दे सकता कि मूल ऐरे नहीं बदलेंगे, इसलिए यह पूरी कॉपी बनाता है।

\n\n

विधि append(contentsOf:): जब गति महत्वपूर्ण हो

\n\n

यदि आपको तीसरा ऐरे बनाए बिना एक ऐरे के तत्वों को दूसरे के अंत में जोड़ना है, तो append(contentsOf:) का उपयोग करें:

\n\n
var numbers = [1, 2, 3]\nlet moreNumbers = [4, 5, 6]\nnumbers.append(contentsOf: moreNumbers)\nprint(numbers) // [1, 2, 3, 4, 5, 6]
\n\n

इस मामले में, Swift एक नया ऐरे नहीं बनाता - यह मौजूदा ऐरे का विस्तार करता है। यदि ऐरे numbers में पर्याप्त आरक्षित मेमोरी (capacity) है, तो नए तत्व केवल खाली जगह में कॉपी हो जाते हैं। यदि नहीं, तो मेमोरी पुनर्वितरण होता है, लेकिन यह फिर भी शून्य से ऐरे बनाने से तेज़ है।

\n\n

प्रो टिप: यदि आप जानते हैं कि आप बहुत सारे तत्व जोड़ेंगे, तो reserveCapacity() के साथ पहले से मेमोरी आवंटित करें:

\n\n
var bigArray: [Int] = []\nbigArray.reserveCapacity(1000)\nfor i in 0..<1000 {\n    bigArray.append(i) // एक भी अतिरिक्त कॉपी नहीं!\n}
\n\n

विधि flatMap: परिवर्तन के साथ ऐरे का विलय

\n\n

कभी-कभी केवल ऐरे को जोड़ना ही नहीं, बल्कि प्रत्येक तत्व को रूपांतरित करना भी आवश्यक होता है। यहाँ flatMap (या वैकल्पिक के लिए compactMap) मदद करता है। कड़ाई से कहें तो, flatMap संग्रहों को "चपटा" करने के लिए है, लेकिन इसका उपयोग संयोजन के लिए भी किया जा सकता है:

\n\n
let arrays = [[1, 2], [3, 4], [5, 6]]\nlet flattened = arrays.flatMap { $0 }\nprint(flattened) // [1, 2, 3, 4, 5, 6]
\n\n

हुड के नीचे, flatMap वही करता है जो append(contentsOf:) के साथ एक लूप करता है। लेकिन कोड साफ और अधिक पठनीय हो जाता है। हालांकि, यदि आपको केवल दो ऐरे को जोड़ना है - flatMap का उपयोग न करें, यह अनावश्यक है।

\n\n

लचीले विलय के लिए reduce(into:)

\n\n

यदि आपके पास ऐरे का एक ऐरे है और आप उन्हें अतिरिक्त तर्क के साथ मर्ज करना चाहते हैं, तो reduce(into:) आज़माएं:

\n\n
let arrayOfArrays = [[1, 2], [3, 4], [5, 6]]\nlet merged = arrayOfArrays.reduce(into: [Int]()) { r                

ब्लॉग

पुस्तक अनुशंसाएँ