दिनांक स्ट्रिंग्स या ऑब्जेक्ट्स का NSArray सॉर्ट करें


86

मेरे पास NSArrayडेट स्ट्रिंग्स (यानी NSString) इस तरह है: "थू, 21 मई 09 19:10:09 -700"

मुझे NSArrayतिथि के अनुसार क्रमबद्ध करने की आवश्यकता है । मैंने तारीख स्ट्रिंग को NSDateपहले किसी ऑब्जेक्ट में बदलने के बारे में सोचा था , लेकिन NSDateऑब्जेक्ट द्वारा सॉर्ट करने के तरीके पर वहां अटक गया ।

धन्यवाद।


चूंकि यह फाउंडेशन फ्रेमवर्क से संबंधित है, और iPhone के लिए विशिष्ट नहीं है।
क्विन टेलर

जवाबों:


110

NSDateNS (म्यूटेबल) सरणी में ऑब्जेक्ट्स के रूप में दिनांक संग्रहीत करें, फिर पैरामीटर के रूप में उपयोग करें -[NSArray sortedArrayUsingSelector:या -[NSMutableArray sortUsingSelector:]पास @selector(compare:)करें। -[NSDate compare:]विधि आपके लिए आरोही क्रम में दिनांक आदेश देगा। यह एक तुलना बनाने की तुलना में सरल है NSSortDescriptor, और अपने स्वयं के तुलनात्मक फ़ंक्शन को लिखने की तुलना में बहुत सरल है। ( NSDateवस्तुएं जानती हैं कि हम कम से कम कुशलता से एक-दूसरे से तुलना कैसे कर सकते हैं क्योंकि हम कस्टम कोड के साथ पूरा करने की उम्मीद कर सकते हैं।)


11
यह स्पष्ट नहीं है कि मूल प्रश्न किसी दिनांक की श्रेणी को सॉर्ट करने, या किसी दिनांक फ़ील्ड वाले ऑब्जेक्ट की एक सरणी को सॉर्ट करने के बारे में पूछ रहा था। यदि यह पूर्व है, तो यह सबसे आसान तरीका है, लेकिन यदि यह बाद वाला है, तो NSSortDescriptor जाने का रास्ता है।
धुँआधार

@ कैसे NSSortDescriptor शून्य तारीखों को संभालता है?
ऐश

आपकी मदद के लिए धन्यवाद, मुझे लगता है कि हमें Apple डॉक्स में अधिक पढ़ना चाहिए लेकिन यह बहुत उबाऊ लगता है, जब तक आप इसका उपयोग नहीं करते हैं।
अन्बोअटेफ

1
क्या आप इसे एक स्निपेट कोड में एक उदाहरण के रूप में दिखा सकते हैं? अग्रिम में धन्यवाद।
uplearnedu.com

115

यदि मेरे पास एक प्रकार NSMutableArrayकी वस्तुओं का एक क्षेत्र है "शुरुआती" जो NSDateमैं NSSortDescriptorनीचे के रूप में उपयोग कर रहा हूं :

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

3
मुझे पता है कि बहुत समय बीत चुका है (जब पिछले उत्तर को स्वीकार कर लिया गया था फिर भी कोई NSSortDescriptor नहीं हो सकता है), लेकिन भविष्य के उपयोग के लिए यह एक उचित उत्तर होना चाहिए।
Vive

1
यह एक भयानक समाधान है। कोड की कुछ पंक्तियों में मेरी समस्या हल कर दी। एक टन @vinzenzweber
प्रत्युषा तेरली

1
वास्तव में ... मैं वास्तव में हैरान था यह पहली बार में काम किया! मुझे लगा कि initWithKey उन शब्दकोशों के लिए आरक्षित है जहाँ कुंजी को परिभाषित किया गया है, लेकिन आपको केवल वस्तुओं की एक सरणी में एक संपत्ति का संदर्भ देना है? प्रकाश को चमकाने दें vinzenzweberskavitchski !!
Whyoz

NSSortDescriptor OS X 10.3 के बाद से 2003 के अंत में आसपास रहा है। यह थोड़ा अलग परिदृश्य है, जहाँ दिनांक किसी अन्य ऑब्जेक्ट में फ़ील्ड है। और भी-आधुनिक एपीआई के साथ, आप -[NSMutableArray sortUsingComparator:](10.6+) का उपयोग कर सकते हैं और एक ब्लॉक पास कर सकते हैं -compare:जो दो क्षेत्रों पर कॉल करने का परिणाम देता है । यह शायद -valueForKey:प्रत्येक वस्तु पर कॉल करने से तेज होगा । आप -sortWithOptions:usingComparator:समवर्ती रूप से भी क्रमबद्ध करने के लिए विकल्पों का उपयोग और पास कर सकते हैं ।
क्विन टेलर

उपरोक्त NSSortDescriptor नील तिथियों को कैसे संभालता है? क्या हमें हताश को यह बताने की आवश्यकता है कि यदि ऐसा है तो उसके साथ क्या करना है, कैसे?
ऐश

17

आप निम्नलिखित जैसे कुछ का उपयोग कर सकते हैं:

//Sort the array of items by  date
    [self.items sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
        return [obj2.date compare:obj1.date];
    }];

लेकिन यह मान लेता है कि तारीख को एक के रूप में संग्रहीत किया जाता NSDateहैNString , जिसे बनाने / करने के लिए कोई समस्या नहीं होनी चाहिए। अधिमानतः, मैं यह भी सलाह देता हूं कि यह कच्चे प्रारूप में डेटा संग्रहीत करना है। इस तरह की स्थितियों में हेरफेर करना आसान बनाता है।


9

आप जगह में छाँटने के लिए ब्लॉक का उपयोग कर सकते हैं:

sortedDatesArray = [[unsortedDatesArray sortedArrayUsingComparator: ^(id a, id b) {
    NSDate *d1 = [NSDate dateWithString: s1];
    NSDate *d2 = [NSDate dateWithString: s2];
    return [d1 compare: d2];
}];

मेरा सुझाव है कि आप अपने सभी स्ट्रिंग्स को दिनांक आइटम से अधिक बार रूपांतरण न करने के लिए सॉर्ट करने से पहले तारीखों में परिवर्तित करें। किसी भी सॉर्टिंग एल्गोरिथ्म आपको सरणी में आइटमों की संख्या (कभी-कभी बहुत अधिक) की तुलना में अधिक स्ट्रिंग को दिनांक रूपांतरण देगा

सॉर्टिंग पर कुछ अधिक: http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html


यह @notoop द्वारा प्रस्तुत समान उप-इष्टतम विचार का एक प्रकार है। किसी भी मामले में, पहले NSDate में परिवर्तित करना निश्चित रूप से जाने का तरीका है।
क्विन टेलर

उन्होंने मूल रूप से मेरे उत्तर को @ नोटऑफ़ के उत्तर के साथ रखा ..... यदि आप मुझसे पूछें तो डबल पोस्ट करने के लिए काफी अनावश्यक हैं ....
डिकोडिंग आर्ट

यह NSDate के सरणी में पार्स डेट स्ट्रिंग्स की तुलना में बहुत धीमा है और फिर NSDate के सरणी को सॉर्ट करता है, क्योंकि वहाँ 2 * (n - 1) बार स्ट्रिंग की अतिरिक्त पार्सिंग होगी। पार्सिंग स्ट्रिंग्स आमतौर पर सीपीयू पर भारी काम करते हैं।
कार्लि

5

इसने मेरे मामले में जो काम किया वह निम्नलिखित था:

    NSArray * aUnsorted = [dataToDb allKeys];
    NSArray * arrKeys = [aUnsorted सॉर्ट किए गए ArrayUsingComparator: ^ NSComparisonResult (आईडी obj1, आईडी obj2) {
        NSDateFormatter * df = [[NSDateFormatter आवंटन] init];
        [df setDateFormat: @ "dd-MM-yyyy"];
        NSDate * d1 = [df dateFromString: (NSString *) obj1];
        NSDate * d2 = [df dateFromString: (NSString *) obj2];
        वापसी [d1 तुलना: d2];
    }];

मेरे पास एक डिक्शनरी थी, जहाँ सभी कुंजियाँ, जहाँ प्रारूप dd-MM-yyyy हैं। और allKeys डिक्शनरी कीज़ को अनसोल्ड कर देता है, और मैं कालानुक्रमिक क्रम में डेटा प्रस्तुत करना चाहता था।


5

आप उपयोग कर सकते हैं sortedArrayUsingFunction:context:। यहाँ एक नमूना है:

NSComparisonResult dateSort(NSString *s1, NSString *s2, void *context) {
    NSDate *d1 = [NSDate dateWithString:s1];
    NSDate *d2 = [NSDate dateWithString:s2];
    return [d1 compare:d2];
}

NSArray *sorted = [unsorted sortedArrayUsingFunction:dateSort context:nil];

ए का उपयोग करते समय NSMutableArray, आप sortArrayUsingFunction:context:इसके बजाय उपयोग कर सकते हैं ।


9
यह एक बुरा विचार है - एक तुलनात्मक फ़ंक्शन तेज़ होना चाहिए, और प्रत्येक तुलना के लिए स्ट्रिंग्स से NSDate ऑब्जेक्ट्स बनाने के लिए नहीं होना चाहिए। यदि आप पहले से ही उपयोग कर रहे हैं - [NSDate तुलना:], बस सरणी में तारीखों को संग्रहीत करें और उपयोग करें -ArrayUsingSelector: सीधे।
क्विन टेलर

मुझे लगता है कि यह एक अच्छा समाधान है यदि आप उन वस्तुओं को छांट रहे हैं जिनके पास पहले से ही एक NSDate क्षेत्र है। नहीं?
GnarlyDog

1
यदि सरणी में पहले से NSDateऑब्जेक्ट हैं, तो आप मेरे उत्तर का उपयोग कर सकते हैं, या यहां तक ​​कि उपयोग कर सकते हैं -[NSMutableArray sortUsingComparator:], जिसे 10.6 में जोड़ा गया था।
क्विन टेलर

यदि आप शब्दकोश की एक ऐसी सरणी का उपयोग कर रहे हैं जिसमें NSString के साथ-साथ कुछ अन्य कुंजी-मूल्य ऑब्जेक्ट्स के लिए तारीख का एक महत्वपूर्ण-मूल्य ऑब्जेक्ट है, तो यह समाधान अब तक का सबसे अच्छा है। बस DateSort फ़ंक्शन के अंदर थोड़ा संशोधन की आवश्यकता है। थम्स अप! :)
इरफान

4

एक बार आपके पास NSDate, आप एक के NSSortDescriptorसाथ बना सकते हैं initWithKey:ascending:और फिर sortedArrayUsingDescriptors:छँटाई करने के लिए उपयोग कर सकते हैं ।


यह दृष्टिकोण काम करेगा, लेकिन -sortedArrayUsingSelector का उपयोग करना: थोड़ा सरल है और एक अतिरिक्त ऑब्जेक्ट बनाने की आवश्यकता नहीं है।
क्विन टेलर

पूर्व-संपादन, प्रश्न का उल्लेख "एक 'तारीख' कुंजी के रूप में किया गया था, इसलिए मैंने माना कि यह वास्तव में वस्तुओं / शब्दकोशों की एक सरणी थी जिसमें एक तारीख के रूप में एक तारीख थी, कच्ची तारीखों की एक सरणी नहीं थी। उस मामले में SortedArrayUsingSelector: अधिक जटिल है, क्योंकि इसमें लुकअप करने के लिए कस्टम सॉर्ट रूटीन लिखने की आवश्यकता होती है।
धुँआधार

हाँ, किसी भी भ्रम के लिए खेद है - मैंने उस संदर्भ को साफ कर दिया क्योंकि वह सिर्फ यह कह रहा था कि वह एक 'तारीख' कुंजी के साथ अपने सरणी को संग्रहीत कर रहा था, और मुझे एहसास हुआ कि यह प्रश्न को और अधिक भ्रमित कर देगा। आप निश्चित रूप से एक अधिक जटिल डेटा संरचना को देखते हुए सापेक्ष जटिलता के बारे में सही हैं।
क्विन टेलर


1

इसे बदलो

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

सेवा

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Date" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

बस कुंजी बदलें: यह Dateहमेशा होना चाहिए

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.