Kaip rūšiuoti NSMutableArray su pasirinktiniais objektais?

Ką noriu padaryti, atrodo gana paprasta, bet negaliu rasti atsakymų internete. Turiu NSMutableArray objektus ir leiskite jiems būti Asmenų objektais. Noriu rūšiuoti NSMutableArray pagal Person.birthDate, kuris yra NSDate .

Manau, kad tai yra susijęs su šiuo metodu:

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

„Java“ norėčiau, kad mano objektas įgyvendintų palyginamą arba naudokite „Collection.sort“ su integruotu naudotojo palygintuvu ... kaip tai darote „Objective-C“?

1111
30 апр. Rustyshelf nustatė balandžio 30 d 2009-04-30 09:10 '09, 9:10, 2009-04-30 09:10
@ 22 atsakymai

Palyginimo metodas

Arba galite įgyvendinti savo objekto palyginimo metodą:

 - (NSComparisonResult)compare:(Person *)otherObject { return [self.birthDate compare:otherObject.birthDate]; } NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(compare:)]; 

NSSortDescriptor (geriau)

arba paprastai dar geriau:

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

Jūs galite lengvai surūšiuoti pagal kelis raktus, pridedant daugiau nei vieną masyvui. Taip pat galima naudoti pasirinktinius lyginamuosius. Peržiūrėkite dokumentus .

Blokai (blizgus!)

Taip pat yra galimybė surūšiuoti su bloku su „Mac OS X 10.6“ ir „iOS 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]; }]; 

Našumas

-compare: ir blokas pagrįsti metodai paprastai yra greitesni nei naudojant NSSortDescriptor , nes pastaroji priklauso nuo KVC. Pagrindinis NSSortDescriptor metodo privalumas yra tai, kad jis suteikia galimybę nustatyti savo rūšiavimo tvarką, o ne duomenis, o tai supaprastina, kad vartotojai galėtų rūšiuoti „ NSTableView “ spustelėdami pavadinimo juostą.

2156
30 апр. Georg Schölly atsakymas balandžio 30 d 2009-04-30 09:25 '09 9:25 val. 2009-04-30 09:25

Žr. „ NSMutableArraysortUsingFunction:context:

Turėsite sukonfigūruoti palyginimo funkciją, kuri priima du objektus (tipo Person , nes lyginate du Person objektus) ir kontekstinį parametrą.

Du objektai yra tik Person atvejai. Trečiasis objektas yra, pavyzdžiui, eilutė. @ "BIRTH".

Ši funkcija grąžina „ NSComparisonResult : ji grąžina „ NSOrderedAscending jei „ PersonA.birthDate < PersonB.birthDate . Ji grąžins „ NSOrderedDescending jei „ PersonA.birthDate > „ PersonB.birthDate . Galiausiai, jis grąžins „ NSOrderedSame jei „ PersonA.birthDate == PersonB.birthDate .

Tai yra grubus pseudokodas; Jums reikės nustatyti, kokią datą reiškia „mažiau nei“, „didesnė nei“ arba „lygi“ kitai datai (pavyzdžiui, lyginant sekundes-s-eras ir tt):

border=0
 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; } 

Jei norite kažką daugiau kompaktiško, galite naudoti trigubus operatorius:

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

Investavimas gali šiek tiek pagreitinti, jei tai darote daug.

97
30 апр. Alex Reynolds atsakymas balandžio 30 d 2009-04-30 09:24 '09 9:24 val. 2009-04-30 09:24

Tai padariau „iOS 4“ naudojant bloką. Turėjau atskirti savo masyvo elementus nuo id iki mano klasės. Šiuo atveju tai yra klasė, vadinama „Įvertinimu“, turinčia nuosavybę, vadinamą taškais.

Jūs taip pat turite nuspręsti, ką daryti, jei jūsų masyvo elementai nesutampa su tipu, šiuo pavyzdžiu ką tik grįžau NSOrderedSame , bet mano kode I, nors ir išimtis.

 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; 

PS: tai rūšiuoti mažėjančia tvarka.

53
25 марта '11 в 1:15 2011-03-25 01:15 atsakymą pateikė „ Chris “ kovo 25 d. 11 d. 1:15 2011-03-25 01:15

Nuo „iOS 4“ taip pat galite naudoti rūšiavimui skirtus blokus.

Šiame konkrečiame pavyzdyje manau, kad jūsų masyvo objektai turi „pozicijos“ metodą, kurį grąžina 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]; 

Pastaba: „surūšiuotas“ masyvas bus automatiškai įdiegtas.

24
16 марта '11 в 21:46 2011-03-16 21:46 atsakymas pateikiamas Leviathan kovo 16 d. 11 val. 21:46 2011-03-16 21:46

Bandžiau viską, bet jis dirbo man. Klasėje turiu kitą klasę su pavadinimu " crimeScene " ir noriu surūšiuoti pagal turtą " crimeScene ".

Jis veikia kaip žavesys:

 NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"crimeScene.distance" ascending:YES]; [self.arrAnnotations sortUsingDescriptors:[NSArray arrayWithObject:sorter]]; 
24
22 нояб. Atsakymą pateikė Fernando Redondo lapkričio 22 d. 2010-11-22 13:51 '10, 13:51, 2010-11-22 13:51

Antrasis George Schölli atsakymas trūksta , tačiau jis veikia gerai.

 NSSortDescriptor *sortDescriptor; sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease]; NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; NSArray *sortedArray; sortedArray = [drinkDetails sortedArrayUsingDescriptor:sortDescriptors]; 
17
06 мая '09 в 19:25 2009-05-06 19:25 atsakė Manueliui Spuhleriui gegužės 06 d., 09:25 2009-05-06 19:25
 NSSortDescriptor *sortDescriptor; sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease]; NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; NSArray *sortedArray; sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors]; 

Ačiū, tai puikiai veikia ...

16
30 марта '11 в 8:54 2011-03-30 08:54 atsakymą pateikė Hardik Darji kovo 30 d. 11 val. 8:54 2011-03-30 08:54

Person objektams reikia įdiegti metodą, pvz., compare: kuris paima kitą Person objektą ir grąžina NSComparisonResult pagal santykį tarp dviejų objektų.

Tada skambinate sortedArrayUsingSelector: su @selector(compare:) , ir tai turėtų būti padaryta.

Yra ir kitų būdų, tačiau, kiek žinau, nėra jokios „Cocoa-Equip“ palyginamos sąsajos. Naudojant „ sortedArrayUsingSelector: greičiausiai tai yra neskausmingiausias būdas tai padaryti.

16
30 апр. atsakymas pateikiamas laisvos vietos 30 Bal 2009-04-30 09:20 '09, 9:20, 2009-04-30 09:20

IOS 4 blokai taupys jus :)

 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 mažas aprašymas

8
14 апр. Atsakymą pateikė Kostiantyn Sokolinskyi balandžio 14 d. 2011-04-14 12:03 '11, 12:03, 2011-04-14 12:03

NSMutableArray naudokite „ sortUsingSelector metodą. Jis rūšiuoja šią vietą nesukurdamas naujo instancijos.

7
09 нояб. atsakymą pateikė DenTheMan, lapkričio 9 d. 2010-11-09 16:47 '10, 16:47, 2010-11-09 16:47

Jei tik rūšiuojate NSNumbers masyvą, galite juos rūšiuoti naudodami 1 skambutį:

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

Tai veikia, nes masyvo objektai ( NSNumber objektai) įgyvendina palyginimo metodą. Jūs galite padaryti tą patį ir NSString objektams, arba netgi naudotojo nustatytų duomenų objektų, kurie įgyvendina palyginimo metodą, masyvui.

Čia yra pavyzdinis kodas, naudojant lyginamuosius blokus. Jis surūšiuoja žodynų masyvą, kuriame kiekvienas žodynas turi skaičių „sort_key“ klavišu.

 #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; }]; 

Pirmiau minėtas kodas aptaria, kaip kiekvienam rūšies raktui gauti sveikasis skaičius, ir juos lyginti kaip pavyzdį, kaip tai padaryti. Kadangi NSNumber objektai įgyvendina palyginimo metodą, jis gali būti perrašytas daug paprastiau:

  #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]; }]; 

arba lyginamoji įstaiga gali būti distiliuota iki 1 eilutės:

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

Aš norėčiau paprastų operatorių ir daug laikinų kintamųjų, nes kodą lengviau skaityti ir lengviau derinti. Bet kokiu atveju kompiliatorius optimizuoja laikinus kintamuosius, taigi visai vienai versijai nėra jokio pranašumo.

5
06 дек. Atsakymas pateikiamas Dinesh_ 06 dec. 2012-12-06 10:51 '12 at 10:51 2012-12-06 10:51

Jūsų tikslui galite naudoti šį bendrąjį metodą. Jis turėtų išspręsti jūsų problemą.

 //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]; 
4
16 апр. MD Aslam Ansari atsakymas, pateiktas balandžio 16 d 2015-04-16 12:17 '15, 12:17, 2015-04-16 12:17

Aš naudoju sortUsingFunction :: kai kuriuose mano projektuose:

 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]; 
4
09 мая '11 в 2:27 2011-05-09 02:27 atsakymas pateikiamas roocell'u gegužės 09 d . 11:27 2011-05-09 02:27

Aš sukūriau nedidelę kategorijų metodų biblioteką, pavadintą „ Linq“ į „ObjectiveC“ , o tai palengvina šį dalyką. Naudodami raktų pasirinkimo birthDate , galite rūšiuoti pagal birthDate taip:

 NSArray* sortedByBirthDate = [input sort:^id(id person) { return [person birthDate]; }] 
4
06 марта '13 в 11:29 2013-03-06 11:29 atsakymą pateikė ColinE kovo 6 d. 13 val. 11:29 2013-03-06 11:29

Aš tiesiog padaryčiau daugiapakopę tvarką pagal naudotojo reikalavimus.

// rūšiuoti reikšmes

  [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

4
04 июня '13 в 13:09 2013-06-04 13:09 atsakymą pateikė Boobalan birželio 14 d. 13:09 2013-06-04 13:09
 -(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted { NSArray *sortedArray; sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) { return [a compare:b]; }]; return [sortedArray mutableCopy]; } 
3
10 янв. Atsakymą pateikė Emile Khattar, sausio 10 d 2013-01-10 18:37 '13, 18:37, 2013-01-10 18:37

Rūšiavimas „ NSMutableArray labai paprastas:

 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
06 сент. Atsakyti Mohit Sep 06 2011-09-06 12:44 '11, 12:44, 2011-09-06 12:44
 NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"_strPrice" ascending:sortFlag selector:@selector(localizedStandardCompare:)] ; 
0
05 янв. atsakymą pateikė vartotojo3622576 05 sausis 2015-01-05 10:00 '15 10:00 val. 2015-01-05 10:00

Greitai protokolai ir funkcinis programavimas leidžia jums lengvai padaryti savo klasę suderinamą su palyginamuoju protokolu, įdiegti protokole reikalaujamus metodus ir tada panaudoti rūšiuojamą (pagal :) aukštą užsakymo funkciją, kad sukurtumėte suskirstytą masyvą be jokių papildomų funkcijų.

 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) 
0
28 марта '17 в 1:14 2017-03-28 01:14 Atsakymą pateikė James Rochabrun , kovo 28 d. 17, 1:14 2017-03-28 01:14

Rūšiuoti naudojant NSComparator

Jei norime rūšiuoti naudotojo objektus, turime pateikti NSComparator , kuris naudojamas vartotojų objektų palyginimui. Blokas grąžina reikšmę NSComparisonResult , nurodydamas dviejų objektų tvarką. Todėl, norėdami surūšiuoti visą masyvą, NSComparator naudojamas taip.

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

Rūšiuoti naudojant „NSSortDescriptor“
Tarkime, kaip pavyzdį, kad mes turime masyvą, kuriame yra pasirinktinės klasės egzempliorių, Darbuotojas turi atributų vardą, pavardę ir amžių. Toliau pateiktas pavyzdys parodo, kaip sukurti NSSortDescriptor, kuris gali būti naudojamas masyvo turinio rūšiavimui didėjančia tvarka pagal amžiaus raktą.

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

Rūšiuoti pagal pasirinktinius vaizdus
Vardai yra stygos, o kai rūšiuojate eilutes, kurios pateikiamos naudotojui, visada turėtumėte naudoti vietinį atitikimą. Dažnai taip pat pageidaujate neatsižvelgti į atvejį. Čia pateikiamas pavyzdys su (localizedStandardCompare :), jei norite organizuoti masyvą pagal pavadinimą ir vardą.

 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]; 

Dėl pagalbos ir diskusijų žr. Https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/SortDescriptors/Articles/Creating.html
http://www.ios-blog.co.uk/tutorials/objective-c/how-to-sort-nsarray-with-custom-objects/

0
16 июня '16 в 12:32 2016-06-16 12:32 atsakymą pateikė Aamiras birželio 16 d. 16 val. 12:32 2016-06-16 12:32

Mano atveju naudoju sortedArrayUsingComparator, kad surūšiuotumėte masyvą. Pažvelkite į žemiau esantį kodą.

 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]; }]; 

Taip pat mano objektas

 @interface ContactListData : JsonData @property(nonatomic,strong) NSString * contactName; @property(nonatomic,strong) NSString * contactSurname; @property(nonatomic,strong) NSString * contactPhoneNumber; @property(nonatomic) BOOL isSelected; @end 
0
13 дек. Emre Gürses atsakymas gruodžio 13 d 2016-12-13 15:22 '16 at 15:22 2016-12-13 15:22
 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(@"==============================="); 
-2
29 окт. atsakymą pateikė Siddhesh Bondre spalio 29 d. 2013-10-29 04:28 '13, 4:28 2013-10-29 04:28