मैं इसमें कस्टम ऑब्जेक्ट्स के साथ एक NSMutableArray कैसे सॉर्ट करूं?


1268

मैं जो करना चाहता हूं वह बहुत सरल लगता है, लेकिन मुझे वेब पर कोई जवाब नहीं मिल रहा है। मेरे पास एक NSMutableArrayऑब्जेक्ट है, और मान लें कि वे 'व्यक्ति' ऑब्जेक्ट हैं। मैं NSMutableArrayPerson.birthDate द्वारा सॉर्ट करना चाहता हूं जो कि ए NSDate

मुझे लगता है कि इसका इस विधि से कुछ लेना देना है:

NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(???)];

जावा में मैं अपनी वस्तु को तुलनात्मक रूप से लागू करूंगा, या एक इनलाइन कस्टम तुलनित्र के साथ कलेक्शंस का उपयोग कर सकता हूं ... आप ऑब्जेक्टिव-सी में पृथ्वी पर कैसे करते हैं?

जवाबों:


2299

विधि की तुलना करें

या तो आप अपनी वस्तु के लिए तुलना-विधि लागू करते हैं:

- (NSComparisonResult)compare:(Person *)otherObject {
    return [self.birthDate compare:otherObject.birthDate];
}

NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(compare:)];

NSSortDescriptor (बेहतर)

या आमतौर पर और भी बेहतर:

NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                           ascending:YES];
NSArray *sortedArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];

आप कई कुंजियों को आसानी से एक से अधिक सरणी में जोड़कर सॉर्ट कर सकते हैं। कस्टम तुलनित्र-विधियों का उपयोग करना संभव है। प्रलेखन पर एक नजर है ।

ब्लॉक (चमकदार)

मैक ओएस एक्स 10.6 और आईओएस 4 के बाद से एक ब्लॉक के साथ छंटनी की संभावना भी है:

NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    NSDate *first = [(Person*)a birthDate];
    NSDate *second = [(Person*)b birthDate];
    return [first compare:second];
}];

प्रदर्शन

-compare:और ब्लॉक आधारित विधियों का उपयोग करने से, काफ़ी तेजी से सामान्य रूप में किया जाएगा NSSortDescriptorके रूप में बाद के KVC पर निर्भर करता है। NSSortDescriptorविधि का प्राथमिक लाभ यह है कि यह कोड के बजाय डेटा का उपयोग करके आपके क्रम को परिभाषित करने का एक तरीका प्रदान करता है, जिससे चीजों को सेट करना आसान हो जाता है ताकि उपयोगकर्ता NSTableViewहेडर पंक्ति पर क्लिक करके सॉर्ट कर सकें ।


66
पहले उदाहरण में एक बग है: आप जन्मतिथि उदाहरण चर की एक वस्तु में दूसरे वस्तु के साथ तुलना करते हैं, बजाय इसके जन्मतिथि चर से।
मार्टिन गजलदेक

90
@Martin: धन्यवाद! इससे पहले कि मैं इसके लिए 75 upvotes मिला इससे पहले कि किसी और ने गौर नहीं किया।
जॉर्ज स्कोली

76
क्योंकि यह स्वीकृत उत्तर है, और इसलिए संभवतः अधिकांश उपयोगकर्ताओं द्वारा निश्चित माना जाता है, इसलिए यह 3rd, ब्लॉक-आधारित उदाहरण को जोड़ने में सहायक हो सकता है ताकि उपयोगकर्ताओं को पता चले कि यह मौजूद है।
jpswain 20

6
@ नारंगी 80: मैंने कोशिश की। मेरे पास कोई मैक नहीं है, इसलिए यदि आप कोड को देख सकते हैं तो यह अच्छा होगा।
जॉर्ज शॉली

11
यदि आपके पास NSMutableArrayi है तो मेथोड का उपयोग करना पसंद करते हैं sortUsingDescriptors, sortUsingFunctionया sortUsingSelector। जहाँ तक सरणी में परिवर्तन योग्य है, मुझे आमतौर पर एक छँटाई की आवश्यकता नहीं है।
Stephan

109

NSMutableArrayविधि देखेंsortUsingFunction:context:

आपको एक तुलना फ़ंक्शन सेट करने की आवश्यकता होगी जो दो ऑब्जेक्ट्स लेता है (प्रकार के Person, चूंकि आप दो Personऑब्जेक्ट्स की तुलना कर रहे हैं ) और एक संदर्भ पैरामीटर।

दो वस्तुएं मात्र उदाहरण हैं Person। तीसरी वस्तु एक स्ट्रिंग है, जैसे @ "जन्मतिथि"।

यह फ़ंक्शन लौटाता है NSComparisonResult: यह लौटाता है NSOrderedAscendingअगर PersonA.birthDate< PersonB.birthDate। यह वापस आ जाएगी NSOrderedDescendingअगर PersonA.birthDate> PersonB.birthDate। अंत में, यह वापस आ जाएगी NSOrderedSameअगर PersonA.birthDate== PersonB.birthDate

यह मोटे तौर पर स्यूडोकोड है; आपको एक तारीख के लिए "कम", "अधिक" या "बराबर" होने के लिए एक और तारीख (जैसे सेकंड-से-अवधि की तुलना करने के लिए) के रूप में मांस का उपयोग करने की आवश्यकता होगी:

NSComparisonResult compare(Person *firstPerson, Person *secondPerson, void *context) {
  if ([firstPerson birthDate] < [secondPerson birthDate])
    return NSOrderedAscending;
  else if ([firstPerson birthDate] > [secondPerson birthDate])
    return NSOrderedDescending;
  else 
    return NSOrderedSame;
}

यदि आप कुछ अधिक कॉम्पैक्ट चाहते हैं, तो आप टर्नरी ऑपरेटरों का उपयोग कर सकते हैं:

NSComparisonResult compare(Person *firstPerson, Person *secondPerson, void *context) {
  return ([firstPerson birthDate] < [secondPerson birthDate]) ? NSOrderedAscending : ([firstPerson birthDate] > [secondPerson birthDate]) ? NSOrderedDescending : NSOrderedSame;
}

यदि आप इसे बहुत करते हैं, तो Inlining शायद इसे थोड़ा गति दे सकता है।


9
SortUsingFunction का उपयोग करना: संदर्भ: संभवत: सबसे सी-ईश तरीका है और निश्चित रूप से सबसे अपठनीय है।
जॉर्ज शॉली

12
इसमें वास्तव में कुछ भी गलत नहीं है, लेकिन मुझे लगता है कि अब बहुत बेहतर विकल्प हैं।
जॉर्ज शॉर्ली

6
शायद, लेकिन मुझे नहीं लगता कि यह जावा पृष्ठभूमि से किसी ऐसे व्यक्ति के लिए कम पठनीय होगा जो जावा के अमूर्त तुलनित्र वर्ग के समान कुछ खोज सकता है, जो कि तुलना करता है (प्रकार obj1, प्रकार obj2)।
एलेक्स रेनॉल्ड्स

5
मुझे समझ में आता है कि आप में से कोई भी ऐसा कोई कारण ढूंढ रहा है जो भी इस पूरी तरह से ठीक जवाब की आलोचना करे, भले ही उस आलोचना में बहुत कम तकनीकी योग्यता हो। अजीब।
एलेक्स रेनॉल्ड्स

1
@ यार: या तो आप पहले पैराग्राफ में दिए गए समाधान का उपयोग कर सकते हैं, या आप कई प्रकार के डिस्क्रिप्टर का उपयोग कर सकते हैं। SortedArrayUsingDescriptors: तर्क के रूप में सॉर्ट डिस्क्रिप्टर की एक सरणी लेता है।
जॉर्ज शॉली

62

मैंने आईओएस 4 में एक ब्लॉक का उपयोग करके ऐसा किया। आईडी से मेरे वर्ग प्रकार के लिए मेरे सरणी के तत्वों को डालना था। इस मामले में यह एक वर्ग था जिसे अंक नामक संपत्ति के साथ स्कोर कहा जाता था।

इसके अलावा, आपको यह तय करने की आवश्यकता है कि यदि आपके सरणी के तत्व सही प्रकार नहीं हैं, तो इस उदाहरण के लिए मैं अभी लौटा हूं NSOrderedSame, हालांकि मेरे कोड में हालांकि मैं एक अपवाद हूं।

NSArray *sorted = [_scores sortedArrayUsingComparator:^(id obj1, id obj2){
    if ([obj1 isKindOfClass:[Score class]] && [obj2 isKindOfClass:[Score class]]) {
        Score *s1 = obj1;
        Score *s2 = obj2;

        if (s1.points > s2.points) {
            return (NSComparisonResult)NSOrderedAscending;
        } else if (s1.points < s2.points) {
            return (NSComparisonResult)NSOrderedDescending;
        }
    }

    // TODO: default is the same?
    return (NSComparisonResult)NSOrderedSame;
}];

return sorted;

पुनश्च: यह अवरोही क्रम में छंटनी है।


6
आपको वहां वास्तव में "(स्कोर *)" कास्ट की आवश्यकता नहीं है, आप बस "स्कोर * s1 = obj1" कर सकते हैं; क्योंकि आईडी खुशी से संकलक से चेतावनी के बिना किसी भी चीज़ के लिए डाली जाएगी :-)
jpswain

सही नारंगी 80 downcastingको कमजोर चर से पहले कलाकारों की आवश्यकता नहीं होती है।
थिसुमरसाइन

आपको लगातार ऊपर या नीचे निल बनाम निल-निल return ((!obj1 && !obj2) ? NSOrderedSame : (obj1 ? NSOrderedAscending : NSOrderedDescending))
छांटना

हे क्रिस, मैं इस कोड की कोशिश की, मैं अपने कार्यक्रम में एक ताज़ा hv करते हैं .. पहली बार मैं सही काम करता हूं, एक अवरोही क्रम आउटपुट मिला .. लेकिन जब मैं ताज़ा करता हूं। (समान डेटा के साथ समान कोड निष्पादित करें) यह बदल गया। आदेश, यह उतर नहीं रहा था .. कहो मैं अपने सरणी में 4 ऑब्जेक्ट्स, 3 एचवी एक ही डेटा, 1 अलग है।
निकेश के

यदि आप वास्तव में ऐसी वस्तुओं की अपेक्षा करते हैं जो "स्कोर" वर्ग की नहीं हैं, तो आपको उन्हें थोड़ा और अधिक ध्यान देने की आवश्यकता है। अन्यथा आपके पास एक ऐसी स्थिति है जहां अन्य == स्कोर 1 <स्कोर 2 == अन्य जो असंगत है और परेशानी पैदा कर सकता है। आप ऐसी मान लौटा सकते हैं, जो अन्य सभी वस्तुओं से पहले स्कोर ऑब्जेक्ट को सॉर्ट करता है, और अन्य सभी ऑब्जेक्ट एक-दूसरे के बराबर सॉर्ट करते हैं।
gnasher729

29

IOS 4 में शुरू करके आप छँटाई के लिए ब्लॉक का भी उपयोग कर सकते हैं।

इस विशेष उदाहरण के लिए मैं मान रहा हूं कि आपके एरे में वस्तुओं की एक 'स्थिति' विधि है, जो एक रिटर्न देती है NSInteger

NSArray *arrayToSort = where ever you get the array from... ;
NSComparisonResult (^sortBlock)(id, id) = ^(id obj1, id obj2) 
{
    if ([obj1 position] > [obj2 position]) 
    { 
        return (NSComparisonResult)NSOrderedDescending;
    }
    if ([obj1 position] < [obj2 position]) 
    {
        return (NSComparisonResult)NSOrderedAscending;
    }
    return (NSComparisonResult)NSOrderedSame;
};
NSArray *sorted = [arrayToSort sortedArrayUsingComparator:sortBlock];

नोट: "सॉर्ट किया गया" सरणी ऑटोरेलिज्ड होगा।


26

मैंने सभी की कोशिश की, लेकिन इसने मेरे लिए काम किया। एक कक्षा में मेरे पास " crimeScene" नाम की एक और कक्षा है , और " crimeScene" की संपत्ति के आधार पर छाँटना चाहते हैं ।

यह एक आकर्षण की तरह काम करता है:

NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"crimeScene.distance" ascending:YES];
[self.arrAnnotations sortUsingDescriptors:[NSArray arrayWithObject:sorter]];

21

जॉर्ज शॉली के दूसरे उत्तर में एक लापता कदम है , लेकिन यह तब ठीक काम करता है।

NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                              ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];

// 's' को जोड़ा क्योंकि समय की बर्बादी जब मैंने कॉपी की और चिपका दी और यह सॉर्ट किए बिना विफल रहा।


विधि कॉल वास्तव में "सॉर्टेडअरेसिंगसिंगस्क्रिप्ट:" है, जिसके अंत में एक 'एस' है।
19

19
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];

धन्यवाद, यह ठीक काम कर रहा है ...


17

आपकी Personवस्तुओं को एक विधि को लागू करने की आवश्यकता है, कहते हैं compare:जो एक और Personवस्तु लेता है , और वापस लौटता हैNSComparisonResult 2 वस्तुओं के बीच संबंध के अनुसार है।

तब तुम sortedArrayUsingSelector:साथ बुलाओगे@selector(compare:) और यह किया जाना चाहिए।

अन्य तरीके भी हैं, लेकिन जहां तक ​​मुझे पता है कि Comparableइंटरफ़ेस का कोई कोको-इक्विव नहीं है। इसका उपयोग करना sortedArrayUsingSelector:शायद सबसे दर्द रहित तरीका है।


9

आईओएस 4 ब्लॉक आपको बचाएंगे :)

featuresArray = [[unsortedFeaturesArray sortedArrayUsingComparator: ^(id a, id b)  
{
    DMSeatFeature *first = ( DMSeatFeature* ) a;
    DMSeatFeature *second = ( DMSeatFeature* ) b;

    if ( first.quality == second.quality )
        return NSOrderedSame;
    else
    {
        if ( eSeatQualityGreen  == m_seatQuality || eSeatQualityYellowGreen == m_seatQuality || eSeatQualityDefault  == m_seatQuality )
        {
            if ( first.quality < second.quality )
                return NSOrderedAscending;
            else
                return NSOrderedDescending;
        }
        else // eSeatQualityRed || eSeatQualityYellow
        {
            if ( first.quality > second.quality )
                return NSOrderedAscending;
            else
                return NSOrderedDescending;
        } 
    }
}] retain];

http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html थोड़ा सा विवरण


8

के लिए NSMutableArray, sortUsingSelectorविधि का उपयोग करें । यह एक नया उदाहरण बनाए बिना इसे जगह देता है।


बस एक अपडेट: मैं भी कुछ ऐसी चीज की तलाश कर रहा था, जो जगह-जगह पर परिवर्तनशील सरणी को छाँट लेती है, अब iOS "के रूप में सभी" सॉर्ट किए गए तरीकों "के लिए" छंटनी "के समान तरीके हैं sortUsingComparator:
जम्मूतवी

7

आप अपने उद्देश्य के लिए निम्न सामान्य विधि का उपयोग कर सकते हैं। इसे आपकी समस्या को हल करना चाहिए।

//Called method
-(NSMutableArray*)sortArrayList:(NSMutableArray*)arrDeviceList filterKeyName:(NSString*)sortKeyName ascending:(BOOL)isAscending{
    NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:sortKeyName ascending:isAscending];
    [arrDeviceList sortUsingDescriptors:[NSArray arrayWithObject:sorter]];
    return arrDeviceList;
}

//Calling method
[self sortArrayList:arrSomeList filterKeyName:@"anything like date,name etc" ascending:YES];

6

यदि आप केवल एक सरणी को सॉर्ट कर रहे हैं NSNumbers, तो आप उन्हें 1 कॉल के साथ सॉर्ट कर सकते हैं:

[arrayToSort sortUsingSelector: @selector(compare:)];

वह काम करता है क्योंकि सरणी ( NSNumberऑब्जेक्ट्स) में ऑब्जेक्ट तुलना पद्धति को लागू करते हैं। आप एक ही काम कर सकते हैंNSString वस्तुओं के , या यहां तक ​​कि कस्टम डेटा ऑब्जेक्ट्स की एक सरणी के लिए जो एक तुलना विधि को लागू करते हैं।

यहाँ कुछ उदाहरण कोड तुलनित्र ब्लॉक का उपयोग कर रहा है। यह शब्दकोशों की एक सरणी को सॉर्ट करता है जहां प्रत्येक शब्दकोश में एक कुंजी "सॉर्ट_की" में एक नंबर शामिल होता है।

#define SORT_KEY @\"sort_key\"

[anArray sortUsingComparator: 
 ^(id obj1, id obj2) 
  {
  NSInteger value1 = [[obj1 objectForKey: SORT_KEY] intValue];
  NSInteger value2 = [[obj2 objectForKey: SORT_KEY] intValue];
  if (value1 > value2) 
{
  return (NSComparisonResult)NSOrderedDescending;
  }

  if (value1 < value2) 
{
  return (NSComparisonResult)NSOrderedAscending;
  }
    return (NSComparisonResult)NSOrderedSame;
 }];

उपरोक्त कोड प्रत्येक प्रकार की कुंजी के लिए पूर्णांक मान प्राप्त करने और उनकी तुलना करने के कार्य के माध्यम से जाता है, इसे कैसे करना है। चूंकि NSNumberऑब्जेक्ट एक तुलना पद्धति को लागू करते हैं, इसलिए इसे बहुत सरल रूप से फिर से लिखा जा सकता है:

 #define SORT_KEY @\"sort_key\"

[anArray sortUsingComparator: 
^(id obj1, id obj2) 
 {
  NSNumber* key1 = [obj1 objectForKey: SORT_KEY];
  NSNumber* key2 = [obj2 objectForKey: SORT_KEY];
  return [key1 compare: key2];
 }];

या तुलनित्र का शरीर 1 पंक्ति तक भी डिस्टिल्ड हो सकता है:

  return [[obj1 objectForKey: SORT_KEY] compare: [obj2 objectForKey: SORT_KEY]];

मैं सरल कथनों और बहुत सारे अस्थायी चरों को पसंद करता हूं क्योंकि कोड पढ़ना आसान है, और डीबग करना आसान है। कंपाइलर वैसे भी अस्थायी चरों को दूर करता है, इसलिए ऑल-इन-वन लाइन संस्करण का कोई लाभ नहीं है।


5

मैंने श्रेणी विधियों की एक छोटी सी लाइब्रेरी बनाई है, जिसे लाइनक टू ऑब्जेक्टिव कहा जाता है , जो इस तरह की चीज़ को और आसान बना देता है। एक कुंजी चयनकर्ता के साथ सॉर्ट विधि का उपयोग करके , आप birthDateनिम्नानुसार सॉर्ट कर सकते हैं:

NSArray* sortedByBirthDate = [input sort:^id(id person) {
    return [person birthDate];
}]

आपको इसे " LINQ to Objective-C " कहना चाहिए।
पीटर मोर्टेंसन

5

मैंने सिर्फ कस्टम आवश्यकता के आधार पर मल्टी लेवल छँटाई की है।

// मानों को छाँटें

    [arrItem sortUsingComparator:^NSComparisonResult (id a, id b){

    ItemDetail * itemA = (ItemDetail*)a;
    ItemDetail* itemB =(ItemDetail*)b;

    //item price are same
    if (itemA.m_price.m_selling== itemB.m_price.m_selling) {

        NSComparisonResult result=  [itemA.m_itemName compare:itemB.m_itemName];

        //if item names are same, then monogramminginfo has to come before the non monograme item
        if (result==NSOrderedSame) {

            if (itemA.m_monogrammingInfo) {
                return NSOrderedAscending;
            }else{
                return NSOrderedDescending;
            }
        }
        return result;
    }

    //asscending order
    return itemA.m_price.m_selling > itemB.m_price.m_selling;
}];

https://sites.google.com/site/greateindiaclub/mobil-apps/ios/multilevelsortinginiosobjectivec


5

मैंने अपने कुछ प्रोजेक्ट्स में SortUsingFunction :: का उपयोग किया है :

int SortPlays(id a, id b, void* context)
{
    Play* p1 = a;
    Play* p2 = b;
    if (p1.score<p2.score) 
        return NSOrderedDescending;
    else if (p1.score>p2.score) 
        return NSOrderedAscending;
    return NSOrderedSame;
}

...
[validPlays sortUsingFunction:SortPlays context:nil];

5

आप कस्टम ऑब्जेक्ट्स के साथ NSMutableArray को सॉर्ट करने के लिए NSSortDescriptor का उपयोग करते हैं

 NSSortDescriptor *sortingDescriptor;
 sortingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                       ascending:YES];
 NSArray *sortArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];

4
-(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted 
{
  NSArray *sortedArray;
  sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 
  {
    return [a compare:b];
 }];
 return [sortedArray mutableCopy];
}

जब एक नया सरणी वापस आ जाता है, तो एक परिवर्तनशील सरणी में कैसे पास किया जाता है। क्यों एक आवरण बनाने के लिए?
vikingosegundo

3

छंटाई NSMutableArrayबहुत सरल है:

NSMutableArray *arrayToFilter =
     [[NSMutableArray arrayWithObjects:@"Photoshop",
                                       @"Flex",
                                       @"AIR",
                                       @"Flash",
                                       @"Acrobat", nil] autorelease];

NSMutableArray *productsToRemove = [[NSMutableArray array] autorelease];

for (NSString *products in arrayToFilter) {
    if (fliterText &&
        [products rangeOfString:fliterText
                        options:NSLiteralSearch|NSCaseInsensitiveSearch].length == 0)

        [productsToRemove addObject:products];
}
[arrayToFilter removeObjectsInArray:productsToRemove];

2

NSComparator का उपयोग करके सॉर्ट करें

यदि हम कस्टम ऑब्जेक्ट्स को क्रमबद्ध करना चाहते हैं, तो हमें कस्टम ऑब्जेक्ट्स की NSComparatorतुलना करने के लिए उपयोग किया जाना चाहिए। ब्लॉक NSComparisonResultदो वस्तुओं के आदेश को निरूपित करने के लिए एक मूल्य देता है । तो क्रमबद्ध करने के लिए पूरे सरणी NSComparatorको निम्न तरीके से उपयोग किया जाता है।

NSArray *sortedArray = [employeesArray sortedArrayUsingComparator:^NSComparisonResult(Employee *e1, Employee *e2){
    return [e1.firstname compare:e2.firstname];    
}];

NSSortDescriptor का उपयोग करने वाले सॉर्ट्स
मान लेते हैं, एक उदाहरण के रूप में, हमारे पास एक सरणी है जिसमें एक कस्टम वर्ग के उदाहरण हैं, कर्मचारी में Firstname, lastname और उम्र के गुण हैं। निम्न उदाहरण दिखाता है कि एक NSSortDescriptor कैसे बनाया जा सकता है जिसका उपयोग उम्र की कुंजी द्वारा आरोही क्रम में सरणी सामग्री को सॉर्ट करने के लिए किया जा सकता है।

NSSortDescriptor *ageDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
NSArray *sortDescriptors = @[ageDescriptor];
NSArray *sortedArray = [employeesArray sortedArrayUsingDescriptors:sortDescriptors];

कस्टम तुलनाओं का उपयोग करके क्रमबद्ध करें
नाम तार हैं, और जब आप उपयोगकर्ता को प्रस्तुत करने के लिए तार छांटते हैं तो आपको हमेशा स्थानीयकृत तुलना का उपयोग करना चाहिए। अक्सर आप एक मामले की असंवेदनशील तुलना भी करना चाहते हैं। अंतिम और पहले नाम से सरणी का आदेश देने के लिए (localizedStandardCompare :) के साथ एक उदाहरण आता है।

NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc]
              initWithKey:@"lastName" ascending:YES selector:@selector(localizedStandardCompare:)];
NSSortDescriptor * firstNameDescriptor = [[NSSortDescriptor alloc]
              initWithKey:@"firstName" ascending:YES selector:@selector(localizedStandardCompare:)];
NSArray *sortDescriptors = @[lastNameDescriptor, firstNameDescriptor];
NSArray *sortedArray = [employeesArray sortedArrayUsingDescriptors:sortDescriptors];

संदर्भ और विस्तृत चर्चा के लिए कृपया देखें: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/SortDescriptors/Articles/Creating.html http : //www.ios-blog.co.uk-tutorials
/ उद्देश्य-सी / कैसे करने वाली तरह-NSArray-साथ-कस्टम वस्तुओं /


1

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

class Person: Comparable {
    var birthDate: NSDate?
    let name: String

    init(name: String) {
        self.name = name
    }

    static func ==(lhs: Person, rhs: Person) -> Bool {
        return lhs.birthDate === rhs.birthDate || lhs.birthDate?.compare(rhs.birthDate as! Date) == .orderedSame
    }

    static func <(lhs: Person, rhs: Person) -> Bool {
        return lhs.birthDate?.compare(rhs.birthDate as! Date) == .orderedAscending
    }

    static func >(lhs: Person, rhs: Person) -> Bool {
        return lhs.birthDate?.compare(rhs.birthDate as! Date) == .orderedDescending
    }

}

let p1 = Person(name: "Sasha")
p1.birthDate = NSDate() 

let p2 = Person(name: "James")
p2.birthDate = NSDate()//he is older by miliseconds

if p1 == p2 {
    print("they are the same") //they are not
}

let persons = [p1, p2]

//sort the array based on who is older
let sortedPersons = persons.sorted(by: {$0 > $1})

//print sasha which is p1
print(persons.first?.name)
//print James which is the "older"
print(sortedPersons.first?.name)

1

मेरे मामले में, मैं एक सरणी को सॉर्ट करने के लिए "SortedArrayUsingComparator" का उपयोग करता हूं। नीचे दिए गए कोड को देखें।

contactArray = [[NSArray arrayWithArray:[contactSet allObjects]] sortedArrayUsingComparator:^NSComparisonResult(ContactListData *obj1, ContactListData *obj2) {
    NSString *obj1Str = [NSString stringWithFormat:@"%@ %@",obj1.contactName,obj1.contactSurname];
    NSString *obj2Str = [NSString stringWithFormat:@"%@ %@",obj2.contactName,obj2.contactSurname];
    return [obj1Str compare:obj2Str];
}];

इसके अलावा मेरी वस्तु है,

@interface ContactListData : JsonData
@property(nonatomic,strong) NSString * contactName;
@property(nonatomic,strong) NSString * contactSurname;
@property(nonatomic,strong) NSString * contactPhoneNumber;
@property(nonatomic) BOOL isSelected;
@end

1

आपको SortDescriptor बनाना होगा और फिर आप नीचे दिए गए SortDescriptor का उपयोग करके nsmutablearray को सॉर्ट कर सकते हैं।

 let sortDescriptor = NSSortDescriptor(key: "birthDate", ascending: true, selector: #selector(NSString.compare(_:)))
 let array = NSMutableArray(array: self.aryExist.sortedArray(using: [sortDescriptor]))
 print(array)

1

नेस्टेड ऑब्जेक्ट्स के लिए इस तरह का उपयोग करें,

NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastRoute.to.lastname" ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSMutableArray *sortedPackages = [[NSMutableArray alloc]initWithArray:[packages sortedArrayUsingDescriptors:@[sortDescriptor]]];

lastRoute एक ऑब्जेक्ट है और वह ऑब्जेक्ट ऑब्जेक्ट को होल्ड करता है, जो कि ऑब्जेक्ट को lastname स्ट्रिंग मान को होल्ड करता है।


0

स्विफ्ट में एरियर को क्रमबद्ध करें


के लिए Swiftyव्यक्ति के नीचे एक बहुत साफ तकनीक विश्व स्तर पर के लिए लक्ष्य से ऊपर प्राप्त करने के लिए है। चलो एक उदाहरण कस्टम वर्ग है Userजिसमें कुछ विशेषताएँ हैं।

class User: NSObject {
    var id: String?
    var name: String?
    var email: String?
    var createdDate: Date?
}

अब हमारे पास एक एरे है जिसे हमें createdDateआरोही और / या अवरोही के आधार पर क्रमबद्ध करना होगा । तो तारीख तुलना के लिए एक फ़ंक्शन जोड़ने देता है।

class User: NSObject {
    var id: String?
    var name: String?
    var email: String?
    var createdDate: Date?
    func checkForOrder(_ otherUser: User, _ order: ComparisonResult) -> Bool {
        if let myCreatedDate = self.createdDate, let othersCreatedDate = otherUser.createdDate {
            //This line will compare both date with the order that has been passed.
            return myCreatedDate.compare(othersCreatedDate) == order
        }
        return false
    }
}

अब extensionके Arrayलिए एक की सुविधा देता है User। सरल शब्दों में, केवल ऐरे के लिए कुछ विधियाँ जोड़ते हैं, जिसमें केवल उसमें Userवस्तुएँ हैं।

extension Array where Element: User {
    //This method only takes an order type. i.e ComparisonResult.orderedAscending
    func sortUserByDate(_ order: ComparisonResult) -> [User] {
        let sortedArray = self.sorted { (user1, user2) -> Bool in
            return user1.checkForOrder(user2, order)
        }
        return sortedArray
    }
}

आरोही क्रम के लिए उपयोग

let sortedArray = someArray.sortUserByDate(.orderedAscending)

अवरोही क्रम के लिए उपयोग

let sortedArray = someArray.sortUserByDate(.orderedAscending)

समान आदेश के लिए उपयोग

let sortedArray = someArray.sortUserByDate(.orderedSame)

में विधि से ऊपर extensionइच्छा केवल सुलभ हो अगर Arrayइस प्रकार का है [User]||Array<User>


0

स्विफ्ट संस्करण: 5.1

यदि आपके पास कोई कस्टम संरचना या वर्ग है और आप उन्हें मनमाने ढंग से क्रमबद्ध करना चाहते हैं, तो आपको एक निर्दिष्ट स्थान पर छंटनी बंद करने वाली कॉलिंग () का उपयोग करना चाहिए। यहाँ एक उदाहरण है जो किसी विशिष्ट गुण पर कस्टम संरचना की एक सरणी का उपयोग कर रहा है:

    struct User {
        var firstName: String
    }

    var users = [
        User(firstName: "Jemima"),
        User(firstName: "Peter"),
        User(firstName: "David"),
        User(firstName: "Kelly"),
        User(firstName: "Isabella")
    ]

    users.sort {
        $0.firstName < $1.firstName
    }

यदि आप इसके स्थान पर सॉर्ट करने के बजाय एक क्रमबद्ध सरणी वापस करना चाहते हैं, तो इस तरह सॉर्ट किए गए () का उपयोग करें:

    let sortedUsers = users.sorted {
        $0.firstName < $1.firstName
    }

0
  let sortedUsers = users.sorted {
    $0.firstName < $1.firstName
 }

सवाल NSMutableArray के बारे में है, स्विफ्ट में एरर्स के संग्रह के बारे में नहीं है
रिकार्डो

-2
NSMutableArray *stockHoldingCompanies = [NSMutableArray arrayWithObjects:fortune1stock,fortune2stock,fortune3stock,fortune4stock,fortune5stock,fortune6stock , nil];

NSSortDescriptor *sortOrder = [NSSortDescriptor sortDescriptorWithKey:@"companyName" ascending:NO];

[stockHoldingCompanies sortUsingDescriptors:[NSArray arrayWithObject:sortOrder]];

NSEnumerator *enumerator = [stockHoldingCompanies objectEnumerator];

ForeignStockHolding *stockHoldingCompany;

NSLog(@"Fortune 6 companies sorted by Company Name");

    while (stockHoldingCompany = [enumerator nextObject]) {
        NSLog(@"===============================");
        NSLog(@"CompanyName:%@",stockHoldingCompany.companyName);
        NSLog(@"Purchase Share Price:%.2f",stockHoldingCompany.purchaseSharePrice);
        NSLog(@"Current Share Price: %.2f",stockHoldingCompany.currentSharePrice);
        NSLog(@"Number of Shares: %i",stockHoldingCompany.numberOfShares);
        NSLog(@"Cost in Dollars: %.2f",[stockHoldingCompany costInDollars]);
        NSLog(@"Value in Dollars : %.2f",[stockHoldingCompany valueInDollars]);
    }
    NSLog(@"===============================");
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.