Kotlin में "सरल" सॉर्टिंग कोड को क्यों तोड़ देती है?
\nनमस्ते साथी डेवलपर! अगर आपने कभी Kotlin में काम किया है और कार्यों की सूची को पहले तारीख और फिर प्राथमिकता के अनुसार सॉर्ट करने की कोशिश की है, तो आपने शायद ऐसी स्थिति देखी होगी जहाँ परिणाम बेतरतीब लगता है। आप अकेले नहीं हैं — "Sort collection by multiple fields in Kotlin" सवाल ने Stack Overflow पर हज़ारों व्यूज़ बटोरे हैं। लगता है इसमें मुश्किल क्या है? लेकिन शैतान हमेशा विवरणों में छिपा होता है।
\nइस लेख में हम Kotlin में मल्टीपल फील्ड्स द्वारा सॉर्टिंग की टॉप गलतियाँ देखेंगे, जो अनुभवी डेवलपर्स भी करते हैं। आप जानेंगे कि sortedWith कैसे काम करता है, क्यों compareBy और thenBy आपके सबसे अच्छे दोस्त हैं, और null के कारण डेटा कैसे न खोएं। चलिए शुरू करते हैं!
गलती #1: Java जैसी सॉर्टिंग — मैन्युअल Comparator का उपयोग
\nKotlin Java नहीं है। लेकिन Java की दुनिया से आने वाले कई लोग ऐसा लिखते हैं:
\nval list = listOf(\n User("Alice", 25),\n User("Bob", 20),\n User("Charlie", 25)\n)\n\nval sorted = list.sortedWith(Comparator { a, b ->\n val ageCompare = a.age.compareTo(b.age)\n if (ageCompare != 0) ageCompare else a.name.compareTo(b.name)\n})\n\nहाँ, यह काम करता है। लेकिन यह पढ़ने में भयानक है, और आप if-else की श्रृंखला में आसानी से उलझ सकते हैं। Kotlin एक सुंदर तरीका प्रदान करता है — कम्पेरेटर फंक्शन्स।
सही तरीका क्या है?
\nval sorted = list.sortedWith(compareBy<User> { it.age }.thenBy { it.name })\n\nछोटा, स्पष्ट, बिना किसी अतिरिक्त लॉजिक के। compareBy प्राथमिक कम्पेरेटर बनाता है, और thenBy द्वितीयक फील्ड्स जोड़ता है। यही है Kotlin में मल्टीपल फील्ड्स द्वारा सॉर्टिंग अपने आदर्श रूप में।
गलती #2: सॉर्टिंग में null को अनदेखा करना
\nमान लीजिए हमारे पास कार्यों की एक सूची है, जहाँ deadline null हो सकता है। अगर आप बस यह लिखते हैं:
tasks.sortedBy { it.deadline }\n\n…तो आपको NullPointerException मिलेगा। Kotlin null के प्रति सख्त है, और यह बहुत अच्छा है। लेकिन क्या होगा अगर null सामान्य है?
\nसमाधान: nullsFirst / nullsLast
\nविशेष रैपर का उपयोग करें:
\nval sorted = tasks.sortedWith(\n compareBy<Task>(nullsLast()) { it.deadline }\n .thenBy { it.priority }\n)\n\nयहाँ nullsLast() सभी null तारीखों को सूची के अंत में रखता है। nullsFirst() भी है — इसके विपरीत। यह समस्या हल करता है, और आपकी Kotlin कलेक्शन सॉर्टिंग सुरक्षित हो जाती है।
गलती #3: sortedBy और sortedWith के बीच भ्रम
\nकई नौसिखिए ऐसा लिखते हैं:
\nlist.sortedBy { it.age }.sortedBy { it.name }\n\nऔर हैरान होते हैं कि नाम के अनुसार सॉर्टिंग उम्र के अनुसार सॉर्टिंग को "ओवरराइड" कर देती है। sortedBy हर बार एक नई सूची बनाता है और केवल एक फील्ड के अनुसार सॉर्ट करता है। अंतिम कॉल मुख्य होता है।
कैसे ठीक करें?
\ncompareBy की श्रृंखला के साथ sortedWith का उपयोग करें:
list.sortedWith(compareBy({ it.age }, { it.name }))\n\nया जटिल लॉजिक के लिए मल्टी-लाइन विकल्प:
\nlist.sortedWith(compareBy<Person> { it.age }.thenByDescending { it.name })\n\nयाद रखें: एक sortedWith कॉल — मल्टीपल फील्ड्स के लिए एक सॉर्टिंग।
\n\nगलती #4: उल्टे क्रम में सॉर्टिंग — गलत जगह पर
\nकभी-कभी उम्र के अनुसार बढ़ते क्रम में, लेकिन नाम के अनुसार घटते क्रम में सॉर्ट करना होता है। सामान्य गलती:
\nlist.sortedByDescending { it.age }.sortedBy { it.name }\n\nफिर वही समस्या — दूसरी सॉर्टिंग पहली को तोड़ देती है। सही तरीका:
\nval sorted = list.sortedWith(\n compareBy<Person> { it.age }\n .thenByDescending { it.name }\n)\n\nया पूर्ण नियंत्रण के लिए:
\nval sorted = list.sortedWith(\n compareBy(Person::age).thenByDescending(Person::name)\n)\n