2009-07-01 18 views
62

सेट में ऑब्जेक्ट्स की संपत्ति के आधार पर NSSet/NSMutableSet में ऑब्जेक्ट्स को सॉर्ट करने का सबसे प्रभावी तरीका क्या है? अभी मैं जिस तरह से कर रहा हूं वह प्रत्येक ऑब्जेक्ट के माध्यम से पुनरावृत्ति कर रहा है, उन्हें NSMutableArray पर जोड़ें, और NSSortDescriptor के साथ उस सरणी को सॉर्ट करें।एनएसएससेट को सॉर्ट करने का सबसे प्रभावी तरीका क्या है?

उत्तर

111

का उपयोग करके देखें

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors]; 

संपादित: आईओएस ≥ 4.0 और मैक ओएस एक्स ≥ 10.6 के लिए आप सीधे वस्तुओं का एक सेट को सॉर्ट करने

[mySet sortedArrayUsingDescriptors:descriptors]; 
+0

छोटा और प्यारा! – Boon

+5

यह पूछताछकर्ता का सुझाव बहुत अलग नहीं है, और शायद मोटे तौर पर गति में समतुल्य है- सभी ऑब्जेक्ट्स एक ऑटोरेलेस्ड एनएसएआरएआरई लौटाता है, और -अर्टेडएरेयूयूइंग डिस्क्रिप्टर: एक अलग एनएसएआरआरई (दोनों अपरिवर्तनीय) लौटाता है। दो सरणी आवंटित करने की लागत एक (मध्यम आकार) सेट में सभी तत्वों की गणना करने से बहुत कम नहीं है, और दो गुना अधिक जगह की आवश्यकता होती है। –

+1

यह ध्यान रखना अच्छा है कि sortedArrayUsingDescriptors: 10.6 केवल विधि है। यदि आप 10.5 को लक्षित कर रहे हैं या इससे पहले कि आप @ क्विनटाइलर के दृष्टिकोण – Austin

2

एनएसएससेट अनियंत्रित वस्तुओं का संग्रह है। सेब संदर्भों को देखकर Arrays संग्रहित आदेश हैं।

NSArray को देखते हुए वहाँ लिंक से पर http://developer.apple.com/documentation/Cocoa/Conceptual/Collections/Articles/sortingFilteringArrays ...

उदाहरण छँटाई के उदाहरण के साथ एक चर्चा है:

NSInteger alphabeticSort(id string1, id string2, void *reverse) 
{ 
    if (*(BOOL *)reverse == YES) { 
     return [string2 localizedCaseInsensitiveCompare:string1]; 
    } 
    return [string1 localizedCaseInsensitiveCompare:string2]; 
} 

// assuming anArray is array of unsorted strings 

NSArray *sortedArray; 

// sort using a selector 
sortedArray = 
    [anArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 

// sort using a function 
BOOL reverseSort = NO; 
sortedArray = 
    [anArray sortedArrayUsingFunction:alphabeticSort context:&reverseSort]; 
+3

वाह, वह विशेष ऐप्पल नमूना कोड बहुत भयानक है। वे शून्य *, एनएसआईएनटेगर, और int का उपयोग क्यों कर रहे हैं जहां एक बूल का उपयोग करना आसान है? NSComparisonResult के बजाय यह एनएसआईएनटेगर क्यों वापस करेगा? मुझे यकीन है कि यह पिछले एपीआई निर्णयों के साथ संगतता के लिए है, लेकिन यह बदसूरत 'बदसूरत है! मैं कोको संग्रह को सॉर्ट करने के लिए फ़ंक्शन के बजाय एक चयनकर्ता (विधि) का उपयोग करने का सुझाव देता हूं - यह आसान और अधिक सुरुचिपूर्ण है। –

+0

@ क्विनटाइलर मैंने अभी जांच की है और, निश्चित रूप से पर्याप्त है, 'sortedArrayUsingFunction: संदर्भ:' के लिए प्रलेखन: कहता है कि फ़ंक्शन से दो 'आईडी' और 'शून्य *' लेने और 'NSInteger' वापस करने की उम्मीद है। उसमें, कम से कम, नमूना सही है। (उन्होंने इसे अद्यतन भी किया है, यह भी कम हो जाता है।) –

15

"सबसे कारगर तरीका" का उपयोग कर सकते आप वास्तव में क्या मतलब है के आधार पर भिन्न। आकस्मिक धारणा (जो पिछले उत्तर बनाती है) एक सेट में ऑब्जेक्ट्स की एक बार की तरह है। इस मामले में, मैं इसे के बीच काफी एक टॉस अप है कहेंगे क्या @cobbal पता चलता है और क्या आप के साथ आया था - शायद निम्नलिखित की तरह कुछ:

NSMutableArray* array = [NSMutableArray arrayWithCapacity:[set count]]; 
for (id anObject in set) 
    [array addObject:anObject]; 
[array sortUsingDescriptors:descriptors]; 

(मैं कहना है कि यह एक टॉस अप है क्योंकि @ cobbal का दृष्टिकोण दो autoreleased सरणियों, इसलिए स्मृति पदचिह्न युगल पैदा करता है। यह वस्तुओं के छोटे सेट के लिए अप्रासंगिक है, लेकिन तकनीकी रूप से, न तो दृष्टिकोण बहुत ही कुशल है।)

हालांकि अगर आप में तत्वों छँटाई कर रहे हैं सेट एक से अधिक बार (और विशेष रूप से यदि यह एक नियमित बात है) यह निश्चित रूप से एक कुशल दृष्टिकोण नहीं है। आप एनएसएमयूटेबलएरे को चारों ओर रख सकते हैं और इसे एनएसएससेट के साथ सिंक्रनाइज़ कर सकते हैं, फिर कॉल -ोर्ट यूजिंग डिस्क्रिप्टर: प्रत्येक बार, लेकिन अगर सरणी पहले ही सॉर्ट हो चुकी है तो भी उसे एन तुलना की आवश्यकता होगी।

कोको अपने आप को क्रमबद्ध क्रम में संग्रह बनाए रखने के लिए एक कुशल दृष्टिकोण प्रदान नहीं करता है। जावा में TreeSet वर्ग है जो ऑब्जेक्ट डालने या हटाए जाने पर क्रमबद्ध क्रम में तत्वों को बनाए रखता है, लेकिन कोको नहीं करता है। यह वास्तव में यह समस्या थी जिसने मुझे अपने स्वयं के उपयोग के लिए कुछ विकसित करने के लिए प्रेरित किया।

डेटा संरचना संरचना ढांचे के हिस्से के रूप में मैंने विरासत में और संशोधित किया, मैंने protocol and a few implementations for sorted sets बनाया। कंक्रीट उपखंडों में से कोई भी क्रमबद्ध क्रम में विशिष्ट वस्तुओं का एक सेट बनाए रखेगा। अभी भी परिष्करण किए जा रहे हैं - सबसे महत्वपूर्ण यह है कि यह परिणाम के आधार पर आधारित है: (जो सेट में प्रत्येक ऑब्जेक्ट को कार्यान्वित करना चाहिए) और अभी तक एक NSSortDescriptor स्वीकार नहीं करता है। (ऑब्जेक्ट्स पर ब्याज की संपत्ति की तुलना करने के लिए एक कामकाज लागू करना है।)

एक संभावित दोष यह है कि ये कक्षाएं (वर्तमान में) एनएस (उत्परिवर्तनीय) सेट के उप-वर्ग नहीं हैं, इसलिए यदि आपको एक पास करना होगा एनएसएससेट, यह आदेश नहीं दिया जाएगा। (प्रोटोकॉल में एक -सेट विधि होती है जो एक एनएसएससेट देता है, जो निश्चित रूप से अनियंत्रित है।) मैं जल्द ही इसे सुधारने की योजना बना रहा हूं, जैसा कि मैंने ढांचे में एनएसएमयूटेबल डिक्शनरी के साथ किया है। प्रतिक्रिया निश्चित रूप से स्वागत है।:-)

0

आप NSSet क्रमबद्ध नहीं कर सकते, क्योंकि "sortedArrayUsingFunction:" NSArray ... और केवल सरणी :)

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors]; 

कार्य सही के साथ सभी ऊपरी संकेत के रूप में काम परिणाम निर्धारित करते हैं, और नहीं की जरूरत है दूसरी तरह :)

8

आईओएस ≥ 5.0 और मैक ओएस एक्स ≥ 10.7 के लिए आप सीधे NSOrderedSet

+0

यह नहीं करता है ' इस सवाल को संबोधित करें, जहां आपके पास मौजूदा एनएसएससेट है और इसे सॉर्ट करना चाहते हैं। – colincameron

0

उपयोग कर सकते हैं OS X 10.7 और iOS 5.0 के बाद से वहाँ NSOrderedSet। आप वस्तुओं को सेट में रखने और उनका ऑर्डर रखने के लिए इसका उपयोग कर सकते हैं। NSMutableOrderedSet में सॉर्ट करने के तरीके हैं। कुछ स्थितियों में यह प्रदर्शन सुधार दे सकता है, क्योंकि आपको क्रमबद्ध वस्तुओं को संग्रहीत करने के लिए NSArray जैसी अलग वस्तु बनाने की आवश्यकता नहीं है।

संबंधित मुद्दे