NSMutableArray-in xüsusi obyektləri ilə necə sıralanır?

Mənim istədiyim şey olduqca sadə görünür, amma cavabları onlayn tapa bilmirəm. NSMutableArray obyektlərim var və bunlar şəxsin obyekti olsun. NSMutableArray NSDate olan Person.birthDate tərəfindən sıralamaq istəyirəm.

Hesab edirəm ki, bu üsulla bir şey var:

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

Java'da mənim obyektim müqayisə edilə bilən və ya Collections.sort istifadə edən bir istifadəçi müqayisəçisi ilə istifadə etmək istərdim ... Bunu Objective-C'de necə edərdiniz?

1111
30 апр. rustyshelf tərəfindən 30 Martda təyin olundu 2009-04-30 09:10 '09 at 9:10 'da 2009-04-30 09:10
@ 22 cavab

Müqayisə üsulu

Və ya obyektiniz üçün müqayisə üsulunu tətbiq edirsiniz:

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

NSSortDescriptor (daha yaxşı)

və ya adətən daha da yaxşıdır:

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

Ardıcıl birdən çox əlavə edərək bir neçə düyməyə görə asanlıqla sıralayabilirsiniz. Xüsusi komparatorlardan da istifadə etmək mümkündür. Sənədlərə baxın.

Bloklar (parlaq!)

Mac OS X 10.6 və iOS 4 ilə blok ilə çeşidlənməsi mümkündür:

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

Performans

-compare: və blok əsaslı üsullar NSSortDescriptor istifadə NSSortDescriptor daha NSSortDescriptor , çünki sonuncu KVC-yə əsaslanır. NSSortDescriptor metodunun əsas üstünlüyü ondan ibarətdir ki, istifadəçilərin NSTableView tıklayaraq bir NSTableView üçün NSTableView çox məlumatı istifadə edərək, sıralama qaydalarınızı müəyyənləşdirmək üçün bir yol təqdim edir.

2156
30 апр. Georg Schölly tərəfindən verilmiş cavabı Apr 30 2009-04-30 09:25 '09 at 9:25 am 2009-04-30 09:25

sortUsingFunction:context: NSMutableArray metoduna baxın sortUsingFunction:context:

İki obyektin qəbul etdiyi bir müqayisəli funksiyanı (iki Person obyektlərini müqayisə etdiyinizdən sonra) və kontekst parametrini konfiqurasiya etmək lazımdır.

İki obyekt yalnız Person nümunəsidir. Üçüncü obyekt, məsələn, bir simli. @ "BIRTH".

Bu funksiya NSComparisonResult funksiyasını qaytarır: PersonA.birthDate < PersonB.birthDate əgər PersonA.birthDate qaytarır. PersonA.birthDate > PersonB.birthDate əgər PersonA.birthDate PersonB.birthDate . Nəhayət, NSOrderedSame , PersonA.birthDate == PersonB.birthDate .

Bu kobud pseudocode; Bir tarixin daha az, daha az və ya başqa bir tarixə bərabər olması üçün nə üçün (məsələn, saniyələr s-dövrlərini və s. Müqayisə etmək üçün) nə müəyyən etmək lazımdır?

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

Daha kompakt bir şey istəyirsinizsə, üçlü operatoru istifadə edə bilərsiniz:

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

Əgər bir çox şey varsa, investisiyalar bir qədər sürətləndirə bilər.

97
30 апр. Alex Reynolds tərəfindən verilmiş cavabı Apr 30 2009-04-30 09:24 '09 at 9:24 am 2009-04-30 09:24

Bunu iOS 4-də blokdan istifadə etdim. Sütun elementlərimdən idim tipinə ayırmaq məcburiyyətindəyəm. Bu vəziyyətdə, bal olaraq adlandırılan bir xüsusiyyət ilə "Qiymətləndirmə" adlı bir sinifdir.

Serialınızın elementləri növü ilə uyğun NSOrderedSame , nə edəcəyinizə də qərar NSOrderedSame , çünki bu nümunə NSOrderedSame , lakin istisna olsa da, mənim 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; 

PS: Bu azalan bir sıradır.

53
25 марта '11 в 1:15 2011-03-25 01:15 Cavab Chris tərəfindən 25 Mart 'da 1:15' də verildi 2011-03-25 01:15

İOS 4 ilə başlayaraq, siz də sıralamaq üçün blokları istifadə edə bilərsiniz.

Bu xüsusi nümunədə, sizin NSInteger olan obyektlərin NSInteger tərəfindən qaytarılmış bir "mövqe" üsuluna malik olduğunu 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]; 

Qeyd: "sıralanan" array avtomatik həyata keçiriləcək.

24
16 марта '11 в 21:46 2011-03-16 21:46 Cavab 16 mart 2011-ci il saat 21 : 40-da verilir

Hər şeyi sınamışam, amma mənim üçün çalışdı. Sınıfta mənim " crimeScene " adı ilə başqa bir sinif var və " crimeScene " əmlakı ilə düzmək istəyirəm.

Bir cazibə kimi işləyir:

 NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"crimeScene.distance" ascending:YES]; [self.arrAnnotations sortUsingDescriptors:[NSArray arrayWithObject:sorter]]; 
24
22 нояб. Cavab 22 noyabrda Fernando Redondo tərəfindən verilir. 2010-11-22 13:51 '10 at 13:51 2010-11-22 13:51

George Schöllinin ikinci cavabı itkin , amma yaxşı işləyir.

 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 Manuel Spuhler'a 06.05.2009 19:25 cavab verib 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]; 

Təşəkkür edirəm, böyük işləyir ...

16
30 марта '11 в 8:54 2011-03-30 08:54 Cavab Hardik Darji tərəfindən 30 Mart 2011- ci il tarixində 8:54 2011-03-30 08:54

Person obyektləri üçün, məsələn, compare: üçün bir metodu həyata keçirmək lazımdır: Bir başqa Person obyektini götürür və NSComparisonResult iki obyekt arasındakı NSComparisonResult görə qaytarır.

Sonra sortedArrayUsingSelector: @selector(compare:) ilə və bu edilməlidir.

Digər yollar var, amma bildiyim qədər, Kakao-Equip müqayisəli interfeys yoxdur. sortedArrayUsingSelector: istifadə sortedArrayUsingSelector: , yəqin ki, bunu ən ağrısız üsuludur.

16
30 апр. Cavab azadlıq verilir 30 Apre 2009-04-30 09:20 '09 da 9:20 'da 2009-04-30 09:20

IOS 4 blokları sizi xilas edəcək :)

 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 az təsviri

8
14 апр. Cavab Kostiantyn Sokolinskyi 14 apr tərəfindən verilir . 2011-04-14 12:03 '11 at 12:03 2011-04-14 12:03

NSMutableArray üçün sortUsingSelector metodundan istifadə edin. Yeni bir instansiya yaratmadan bu yeri sıralar.

7
09 нояб. Cavab DenTheMan 09 noyabr tarixində verilir. 2010-11-09 16:47 '10 at 16:47 2010-11-09 16:47

Yalnız bir NSNumbers , bunları 1 zəngdən istifadə edə bilərsiniz:

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

Bu işləyir, çünki NSNumber obyektlər ( NSNumber obyektləri) müqayisə üsulunu tətbiq edir. NSString obyektləri üçün və ya hətta müqayisə metodunu tətbiq edən istifadəçi müəyyən edilmiş məlumat obyektlərinin bir sıra üçün eyni ola bilərsiniz.

Burada müqayisə bloklarını istifadə edən nümunə bir koddur. Hər bir lüğətdə "sort_key" düyməsində bir ədəd olduğu bir sıra lüğətlər sırası.

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

Yuxarıdakı kod, hər bir növ açar üçün tam dəyər almaq və bunu necə bir nümunə kimi müqayisə etmək işini müzakirə edir. NSNumber obyektləri müqayisə metodunu tətbiq NSNumber , daha çox yazıla bilər:

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

ya da müqayisə etmə orqanı 1 xəttinə qədər hətta distillə edilə bilər:

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

Kod sadə operatorları və çox müvəqqəti dəyişənləri üstün tuturam, çünki kodu oxumaq daha asan və debug etmək daha asandır. Hər halda, derleyici müvəqqəti dəyişənləri optimallaşdırır, buna görə hamısı bir-birinin versiyası üçün heç bir üstünlük yoxdur.

5
06 дек. Cavab Dinesh_ 06 dekabr verilir . 2012-12-06 10:51 '12 at 10:51 2012-12-06 10:51

Siz məqsədiniz üçün aşağıdakı ümumi üsuldan istifadə edə bilərsiniz. Probleminizi həll etməlidir.

 //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 апр. Aprelin 16-da MD Aslam Ansari tərəfindən verilmiş cavab 2015-04-16 12:17 '15 at 12:17 2015-04-16 12:17

Mən bəzi layihələrdə SortUsingFunction istifadə etdim :

 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 Cavab 09.12.11 tarixində 2 : 27-də roocell tərəfindən verilmişdir 2011-05-09 02:27

Linq adlı ObjectiveC adlı kosmik metodları kiçik bir kitabxana yaratdım, bu da onu asanlaşdırır. birthDate metodunu əsas selector ilə istifadə edərək, birthDate ilə aşağıdakı kimi sıralaya bilərsiniz:

 NSArray* sortedByBirthDate = [input sort:^id(id person) { return [person birthDate]; }] 
4
06 марта '13 в 11:29 2013-03-06 11:29 Cavab ColinE tərəfindən 06 Mart 'da veriləcək 11:29 2013-03-06 11:29

Yalnız istifadəçi tələblərinə əsaslanaraq çox səviyyəli bir növ düzəldim.

// dəyərləri sıralayın

  [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 Cavab Boobalan tərəfindən 04 İyun '13 'də saat 13:09' da verilir. 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 янв. Cavab Emile Xattar tərəfindən verilir 2013-01-10 18:37 '13, saat 18:37 'da 2013-01-10 18:37

Sortlaşdırma NSMutableArray çox sadədir:

 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 сент. Mohit Sep 06-a cavab verin 2011-09-06 12:44 '11 at 12:44 2011-09-06 12:44
 NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"_strPrice" ascending:sortFlag selector:@selector(localizedStandardCompare:)] ; 
0
05 янв. Cavab user3622576 Jan 05 tərəfindən verilir 2015-01-05 10:00 '15 saat 10:00 'da 2015-01-05 10:00

Tez protokollar və funksional proqramlaşdırma, sınıftan müqayisəli protokolla uyğunlaşmaq, protokolun tələb etdiyi metodları həyata keçirmək və təsadüfi sıralanan bir dizi yaratmaq üçün sıralanan (by :) yüksək sifariş funksiyasından istifadə etmək üçün asanlaşdırır, dəyişən array istifadə etmək lazımdır.

 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 Cavab Ceyms Roçabun tərəfindən 28 Mart 'da 1:14' də 2017-03-28 01:14 'də verilir

NSComparator istifadə edərək sırala

Istifadəçi obyektlərini sıralamaq istəyiriksə, istifadəçi obyektlərini müqayisə etmək üçün istifadə olunan bir NSComparator . Blok iki obyektin sırasını göstərmək üçün NSComparisonResult dəyərini qaytarır. Buna görə, bütün dizi sıralamaq üçün NSComparator istifadə olunur.

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

NSSortDescriptor istifadə edərək sırala
Məsələn nümunə olaraq, xüsusi bir sinif nümunələri olan bir sıra var, Çalışan özniteliklerine ilk ismini, soyadını və yaşını verir. Aşağıdakı misalda, bir dizinin məzmununu yaşa görə açaraq sıralamaq üçün istifadə edilə bilən bir NSSortDescriptor yaratmağı göstərir.

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

Xüsusi görünüşlər istifadə edərək sıralayın
Adlar strings və istifadəçiyə təqdim etmək üçün strings sıralandıqda həmişə lokallaşdırılmış eşleme istifadə etməlisiniz. Çoğunlukla, bir halda, duyarsız bir karşılaştırma yapmak isteriz. Burada nümunə (localizedStandardCompare :) adı və adı ilə bir sıra təşkil etməkdir.

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

Yardım və müzakirə üçün https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/SortDescriptors/Articles/Creating.html səhifəsinə baxın.
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 cavab 16 iyun 16: 16-da Aamir tərəfindən verilir. 2016-06-16 12:32

Mənim vəziyyətimdə array sıralamaq üçün SortedArrayUsingComparator istifadə edirəm. Aşağıdakı kodu baxın.

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

Mənim də obyektim

 @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'in cevaplaması 13 dekabr 2016-12-13 15:22 '16 'da 15:22' də 2016-12-13 15:22 'də
 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 окт. Cavab 29 oktyabrda Siddhesh Bondre tərəfindən verilir . 2013-10-29 04:28 '13 'da 4:28' də 2013-10-29 04:28