👩👩👧👦: एक इमोजी जो डेवलपर्स को पागल कर देता है
\n\nकल्पना करें: आप iOS ऐप बना रहे हैं, टेक्स्ट प्रोसेस कर रहे हैं, कैरेक्टर गिन रहे हैं। सब कुछ सही चल रहा है, जब तक कि तीन महिलाओं और दो लड़कियों वाला फैमिली इमोजी नहीं आता। स्क्रीन पर एक ही सिंबल दिखता है, लेकिन Swift कहता है कि यह... 4 कैरेक्टर है? या 7? या 11? यह समस्या जानी-पहचानी लगती है? Unicode और Swift Strings की दुनिया में आपका स्वागत है!
\n\nयह सवाल Stack Overflow पर Swift सेक्शन में सबसे लोकप्रिय में से एक है। और सही भी है। स्ट्रिंग की सादगी कंपोजिट इमोजी के साथ एक असली पहेली बन जाती है। इस लेख में हम सिर्फ यह नहीं बताएंगे कि ऐसा क्यों होता है, बल्कि Swift में ऐसी स्ट्रिंग के साथ सही तरीके से काम करना भी सिखाएंगे। अगर आप Swift में कोड करते हैं और यूज़र इनपुट, इमोजी या इंटरनेशनलाइज़ेशन से जूझते हैं, तो यह लेख आपके लिए है।
\n\n🔍 समस्या: "इस स्ट्रिंग में कितने कैरेक्टर हैं?"
\n\nचलिए सीधे मुद्दे पर आते हैं। Xcode Playground खोलें और यह कोड लिखें:
\n\nimport Foundation\n\nlet familyEmoji = "👩👩👧👦"\nprint(familyEmoji.count) // 1? 4? 7?\n\n\nअगर आपको 1 की उम्मीद है, तो आप यूज़र के नज़रिए से सही हैं। अगर 4 (चार आकृतियाँ) की उम्मीद है, तो वह भी तार्किक है। Swift 1 ही लौटाएगा। लेकिन familyEmoji.unicodeScalars.count ट्राई करें — तो 7 मिलेगा! और utf16.count से 11 आएगा।
पहेली क्या है? इमोजी 👩👩👧👦 एक कंपोजिट ग्राफीम क्लस्टर है। यह कई Unicode स्केलर से बना है, जो अदृश्य ZWJ (Zero Width Joiner) से जुड़े हैं। Swift ऐसे सीक्वेंस को एक दिखने वाला कैरेक्टर (ग्राफीम) मानता है, जो यूज़र के लिए सही है, लेकिन स्ट्रिंग के अंदरूनी हिस्से से काम करते समय भ्रम पैदा करता है।
\n\n🧱 इमोजी की शारीरिक रचना: स्केलर, क्लस्टर और ZWJ
\n\nजादू समझने के लिए, हमारे इमोजी को उसके भागों में तोड़ते हैं। Unicode का हर कैरेक्टर एक स्केलर (न्यूमेरिक कोड) है। 👩👩👧👦 के लिए सीक्वेंस इस तरह दिखता है:
\n\nlet scalars = familyEmoji.unicodeScalars\nfor scalar in scalars {\n print(scalar.value, scalar.properties.name ?? "unknown")\n}\n// आउटपुट (सरलीकृत):\n// 128105 (WOMAN)\n// 8205 (ZERO WIDTH JOINER)\n// 128105 (WOMAN)\n// 8205 (ZERO WIDTH JOINER)\n// 128103 (GIRL)\n// 8205 (ZERO WIDTH JOINER)\n// 128102 (BOY)\n\n\nदेखा? चार आकृतियाँ (दो महिलाएं, एक लड़की, एक लड़का) तीन अदृश्य ZWJ (कोड 8205) से जुड़ी हैं। Swift, Unicode मानक का पालन करते हुए, पूरे सीक्वेंस को एक विस्तारित ग्राफीम क्लस्टर मानता है। यही कारण है कि .count 1 लौटाता है — यह "यूज़र कैरेक्टर" की संख्या है।
🔄 तरीकों की तुलना: count vs unicodeScalars vs utf16
\n\nचलिए इसे व्यवस्थित करते हैं। स्ट्रिंग "👩👩👧👦" के लिए हमें तीन अलग-अलग जवाब मिलते हैं, यह इस पर निर्भर करता है कि हम कौन सा API इस्तेमाल करते हैं:
- \n
.count(ग्राफीम क्लस्टर) —1। UI और UILabel में दिखाने के लिए सही। \n .unicodeScalars.count(Unicode स्केलर) —7। लो-लेवल टेक्स्ट प्रोसेसिंग के लिए उपयोगी। \n .utf16.count(UTF-16 कोड यूनिट) —11। Objective-C NSString के साथ संगतता के लिए। \n .utf8.count(UTF-8 बाइट्स) —25। नेटवर्क और फ़ाइलों के साथ काम करने के लिए। \n
इनमें से हर तरीका अपने काम के लिए सही है। शुरुआती लोगों की गलती टेक्स्ट फील्ड में लंबाई सीमित करने के लिए .count का उपयोग करना है (जैसे "140 कैरेक्टर से अधिक नहीं")। यूज़र के लिए "👩👩👧👦" एक कैरेक्टर है, और 140 ऐसे इमोजी की सीमा सामान्य है। लेकिन अगर आप डेटाबेस में फिक्स्ड बाइट लेंथ वाली स्ट्रिंग स्टोर कर रहे हैं — तो आपको .utf8.count चाहिए।