लुआ में स्ट्रिंग्स अपरिवर्तनीय हैं। इसका मतलब है कि किसी भी समाधान जो स्ट्रिंग में पाठ को प्रतिस्थापित करता है, वांछित सामग्री के साथ एक नई स्ट्रिंग का निर्माण करना समाप्त कर देना चाहिए। किसी अन्य चरित्र के साथ एक वर्ण को बदलने के विशिष्ट मामले के लिए, आपको मूल स्ट्रिंग को उपसर्ग भाग और एक पोस्टफिक्स भाग में विभाजित करने की आवश्यकता होगी, और उन्हें नई सामग्री के चारों ओर एक साथ जोड़ना होगा।
अपने कोड पर यह बदलाव:
function replace_char(pos, str, r)
return str:sub(1, pos-1) .. r .. str:sub(pos+1)
end
लुआ सीधा करने का सबसे सीधा अनुवाद है। यह संभवतः अधिकांश उद्देश्यों के लिए पर्याप्त तेज़ है। मैंने बग तय कर दिया है कि उपसर्ग पहले pos-1
वर्णों का होना चाहिए, और इस तथ्य का लाभ उठाया कि यदि string.sub
पर अंतिम तर्क गुम है तो यह -1
माना जाता है जो स्ट्रिंग के अंत के बराबर है।
लेकिन ध्यान दें कि यह कई अस्थायी स्ट्रिंग बनाता है जो स्ट्रिंग स्टोर में चारों ओर लटकाएंगे जब तक कि कचरा संग्रह उन्हें खाए। उपसर्ग और पोस्टफिक्स के लिए अस्थायी किसी भी समाधान से बचा नहीं जा सकता है। लेकिन इसे दूसरे द्वारा उपभोग करने वाले पहले ..
ऑपरेटर के लिए अस्थायी बनाना होगा।
यह संभव है कि दो वैकल्पिक दृष्टिकोणों में से एक तेज़ी से हो सके। पहले solution offered by Paŭlo Ebermann है, लेकिन एक छोटी सी ट्वीक साथ:
function replace_char2(pos, str, r)
return ("%s%s%s"):format(str:sub(1,pos-1), r, str:sub(pos+1))
end
यह string.format
का उपयोग करता है उम्मीद है कि यह अतिरिक्त अस्थायी वस्तुओं की जरूरत के बिना अंतिम बफर आकार अनुमान लगा सकते हैं में परिणाम की विधानसभा करते हैं।
लेकिन सावधान रहना है कि string.format
किसी भी स्ट्रिंग में किसी भी \0
पात्रों के साथ मुद्दों है की संभावना है कि वह अपने %s
प्रारूप से होकर गुजरता है। विशेष रूप से, चूंकि इसे मानक सी के sprintf()
फ़ंक्शन के संदर्भ में लागू किया गया है, इसलिए यह अपेक्षा करना उचित होगा कि इसे \0
की पहली घटना में प्रतिस्थापित स्ट्रिंग को समाप्त कर दिया जाए। (एक टिप्पणी में उपयोगकर्ता Delusional Logic द्वारा नोट किया गया।)
एक तीसरा विकल्प है कि मन में आता है यह है:
function replace_char3(pos, str, r)
return table.concat{str:sub(1,pos-1), r, str:sub(pos+1)}
end
table.concat
कुशलता से एक अंतिम परिणाम में स्ट्रिंग की एक सूची कोनकैटेनेट्स किया गया। इसमें एक वैकल्पिक दूसरा तर्क है जो तारों के बीच सम्मिलित करने के लिए पाठ है, जो ""
पर डिफ़ॉल्ट है जो हमारे उद्देश्य के अनुरूप है।
मेरा अनुमान है कि जब तक कि आपके तार बहुत बड़े न हों और आप अक्सर इस प्रतिस्थापन को करते हैं, तो आप इन विधियों के बीच कोई व्यावहारिक प्रदर्शन अंतर नहीं देखेंगे। हालांकि, मैं पहले आश्चर्यचकित हूं, इसलिए यह सत्यापित करने के लिए अपने आवेदन को प्रोफाइल करें कि एक बाधा है, और बेंचमार्क संभावित समाधान सावधानी से।
गहराई से स्पष्टीकरण के लिए धन्यवाद – dotminic
यह पुराना है। लेकिन मैंने अभी लिखा कुछ कोड में मामूली बग को हल कर लिया है। यह पता चला है कि '' replace_char2'' विधि शून्य ('' \ 0'') वर्णों को सम्मिलित नहीं करती है। –
@DelusionalLogic अच्छा बिंदु। 'string.format' मानक सी के 'sprintf()' फ़ंक्शन पर दृढ़ता से आधारित है, और इसमें एम्बेडेड एनयूएल बाइट्स के साथ समस्याएं होने की संभावना है। – RBerteig