Bagaimana cara saya mengurutkan NSMutableArray dengan objek khusus di dalamnya?

1268

Apa yang ingin saya lakukan tampaknya cukup sederhana, tetapi saya tidak dapat menemukan jawaban di web. Saya memiliki NSMutableArrayobjek, dan katakanlah mereka adalah objek 'Person'. Saya ingin mengurutkan NSMutableArrayberdasarkan Person.birthDate yang merupakan NSDate.

Saya pikir ini ada hubungannya dengan metode ini:

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

Di Jawa, saya akan membuat objek saya mengimplementasikan Comparable, atau menggunakan Collections.sort dengan komparator kustom sebaris ... bagaimana Anda melakukannya di Objective-C?

rustyshelf
sumber

Jawaban:

2299

Bandingkan metode

Entah Anda menerapkan metode perbandingan untuk objek Anda:

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

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

NSSortDescriptor (lebih baik)

atau biasanya lebih baik:

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

Anda dapat dengan mudah mengurutkan berdasarkan beberapa kunci dengan menambahkan lebih dari satu ke array. Menggunakan metode pembanding khusus juga dimungkinkan. Lihat dokumentasi .

Blok (mengkilap!)

Ada juga kemungkinan penyortiran dengan blok sejak Mac OS X 10.6 dan 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];
}];

Performa

Metode -compare:dan berbasis blok akan sedikit lebih cepat, secara umum, daripada menggunakan NSSortDescriptorkarena yang terakhir bergantung pada KVC. Keuntungan utama dari NSSortDescriptormetode ini adalah ia menyediakan cara untuk mendefinisikan urutan pesanan Anda menggunakan data, bukan kode, yang membuatnya mudah misalnya mengatur hal-hal sehingga pengguna dapat mengurutkan NSTableViewdengan mengklik pada baris header.

Georg Schölly
sumber
66
Contoh pertama memiliki bug: Anda membandingkan variabel instance birthDate di satu objek dengan objek lain itu sendiri, bukan variabel birthDate-nya.
Martin Gjaldbaek
90
@ Martin: Terima kasih! Lucu bahwa tidak ada orang lain yang memperhatikan sebelum saya mendapat 75 upvotes untuk itu.
Georg Schölly
76
Karena ini adalah jawaban yang diterima, dan karena itu mungkin dianggap pasti oleh sebagian besar pengguna, mungkin bermanfaat untuk menambahkan contoh ke-3, berbasis-blok sehingga pengguna akan sadar bahwa itu juga ada.
jpswain
6
@ orange80: Saya mencobanya. Saya tidak memiliki Mac lagi, jadi alangkah baiknya jika Anda bisa melihat kodenya.
Georg Schölly
11
Jika Anda memiliki NSMutableArraysaya lebih suka menggunakan metode sortUsingDescriptors, sortUsingFunctionatau sortUsingSelector. Sejauh array bisa berubah saya biasanya tidak memerlukan salinan yang diurutkan.
Stephan
109

Lihat NSMutableArraymetodenyasortUsingFunction:context:

Anda perlu mengatur fungsi bandingkan yang mengambil dua objek (bertipe Person, karena Anda membandingkan dua Personobjek) dan parameter konteks .

Dua objek hanya contoh Person. Objek ketiga adalah string, misalnya @ "birthDate".

Fungsi ini mengembalikan NSComparisonResult: Ini mengembalikan NSOrderedAscendingjika PersonA.birthDate< PersonB.birthDate. Ini akan kembali NSOrderedDescendingjika PersonA.birthDate> PersonB.birthDate. Akhirnya, itu akan kembali NSOrderedSamejika PersonA.birthDate== PersonB.birthDate.

Ini adalah kodesemu kasar; Anda perlu menyempurnakan apa artinya satu tanggal menjadi "kurang", "lebih" atau "sama" dengan tanggal lain (seperti membandingkan detik-sejak-zaman dll):

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

Jika Anda menginginkan sesuatu yang lebih ringkas, Anda dapat menggunakan operator ternary:

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

Inlining mungkin bisa mempercepat ini sedikit, jika Anda melakukan ini banyak.

Alex Reynolds
sumber
9
Menggunakan sortUsingFunction: context: mungkin cara yang paling c-ish dan jelas yang paling tidak dapat dibaca.
Georg Schölly
12
Tidak ada yang salah dengan itu, tetapi saya pikir sekarang ada alternatif yang jauh lebih baik.
Georg Schölly
6
Mungkin, tetapi saya tidak berpikir itu akan kurang dapat dibaca oleh seseorang dari latar belakang Java yang mungkin mencari sesuatu yang mirip dengan kelas pembanding abstrak Jawa, yang mengimplementasikan membandingkan (Jenis objek 1, Jenis objek 2).
Alex Reynolds
5
Saya merasa beberapa dari Anda mencari alasan apa pun untuk mengkritik jawaban yang sangat baik ini, bahkan jika kritik itu memiliki sedikit kelebihan teknis. Aneh.
Alex Reynolds
1
@ Yar: Anda bisa menggunakan solusi yang saya berikan di paragraf pertama, atau Anda menggunakan beberapa deskriptor pengurutan. sortArrayUsingDescriptors: mengambil array yang menguraikan deskripsi sebagai argumen.
Georg Schölly
62

Saya melakukan ini di iOS 4 menggunakan blok. Harus membuang elemen array saya dari id ke tipe kelas saya. Dalam hal ini adalah kelas yang disebut Skor dengan properti yang disebut poin.

Anda juga perlu memutuskan apa yang harus dilakukan jika elemen array Anda bukan tipe yang tepat, untuk contoh ini saya baru saja kembali NSOrderedSame, namun dalam kode saya, saya meskipun pengecualian.

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: Ini mengurutkan dalam urutan menurun.

Chris
sumber
6
Anda tidak benar-benar membutuhkan gips "(Skor *)" di sana, Anda cukup melakukan "Skor * s1 = obj1;" karena id akan dengan senang hati melakukan apa saja tanpa peringatan dari kompiler :-)
jpswain
orange80 kanan downcastingtidak memerlukan gips sebelum variabel lemah.
musim panas
Anda harus mengurutkan nil vs. tidak-nil ke atas atau bawah secara konsisten, sehingga pengembalian akhir default mungkinreturn ((!obj1 && !obj2) ? NSOrderedSame : (obj1 ? NSOrderedAscending : NSOrderedDescending))
Scott Corscadden
heh Chris, saya mencoba kode ini, saya melakukan refresh dalam program saya .. untuk pertama kalinya saya melakukan pekerjaan yang benar, mendapat hasil pesanan menurun .. tetapi ketika saya menyegarkan. (jalankan kode yang sama dengan data yang sama) itu berubah urutannya, itu tidak turun .. Katakanlah saya hv 4 objek dalam array saya, 3 hv data yang sama, 1 berbeda.
Nikesh K
Jika Anda benar-benar mengharapkan objek yang bukan dari kelas "Skor", Anda perlu mengurutkannya sedikit lebih hati-hati. Kalau tidak, Anda memiliki situasi di mana lainnya == score1 <score2 == lainnya yang tidak konsisten dan dapat menyebabkan masalah. Anda bisa mengembalikan nilai yang menyiratkan menyortir objek Skor sebelum semua objek lainnya, dan semua objek lainnya menyortir sama satu sama lain.
gnasher729
29

Mulai di iOS 4 Anda juga dapat menggunakan blok untuk menyortir.

Untuk contoh khusus ini saya mengasumsikan bahwa objek dalam array Anda memiliki metode 'posisi', yang mengembalikan sebuah 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];

Catatan: array "diurutkan" akan autoreleased.

raksasa
sumber
26

Saya sudah mencoba semua, tetapi ini berhasil untuk saya. Di kelas saya memiliki kelas lain bernama " crimeScene", dan ingin mengurutkan berdasarkan properti " crimeScene".

Ini berfungsi seperti pesona:

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

Ada langkah yang hilang dalam jawaban kedua Georg Schölly , tetapi itu berfungsi dengan baik kemudian.

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

// menambahkan 's' karena waktu terbuang ketika saya menyalin dan menempel dan gagal tanpa 's' di SortArrayUsingDescriptors

Manuel Spuhler
sumber
Pemanggilan metode sebenarnya "sortArrayUsingDescriptors:", dengan 's' di akhir.
CIFilter
19
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];

Terima kasih, ini berfungsi dengan baik ...

Hardik Darji
sumber
17

PersonObjek Anda perlu menerapkan metode, katakan compare:yang mengambil Personobjek lain , dan kembali NSComparisonResultsesuai dengan hubungan antara 2 objek.

Kemudian Anda akan menyebutnya sortedArrayUsingSelector:dengan @selector(compare:)dan itu harus dilakukan.

Ada cara lain, tapi sejauh yang saya tahu tidak ada Kakao-equiv dari Comparableantarmuka. Menggunakan sortedArrayUsingSelector:mungkin merupakan cara yang paling mudah untuk melakukannya.

ruang bebas
sumber
9

iOS 4 blok akan menghemat Anda :)

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 sedikit deskripsi

Kostiantyn Sokolinskyi
sumber
8

Untuk NSMutableArray, gunakan sortUsingSelectormetode. Itu mengurutkannya-tempat, tanpa membuat contoh baru.

DenTheMan
sumber
Hanya pembaruan: Saya juga sedang mencari sesuatu yang mengurutkan array yang bisa berubah di tempat, sekarang ada metode "sortUsing" yang setara untuk semua metode "sortArrayUsing" pada iOS 7. Seperti sortUsingComparator:.
jmathew
7

Anda dapat menggunakan metode generik berikut untuk tujuan Anda. Itu harus menyelesaikan masalah Anda.

//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];
MD Aslam Ansari
sumber
6

Jika Anda hanya mengurutkan array NSNumbers, Anda dapat mengurutkannya dengan 1 panggilan:

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

Itu berfungsi karena objek dalam array ( NSNumberobjek) menerapkan metode bandingkan. Anda bisa melakukan hal yang sama untuk NSStringobjek, atau bahkan untuk array objek data kustom yang menerapkan metode perbandingan.

Berikut ini beberapa contoh kode menggunakan blok pembanding. Itu mengurutkan array kamus di mana setiap kamus menyertakan angka dalam kunci "sort_key".

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

Kode di atas bekerja untuk mendapatkan nilai integer untuk setiap kunci sortir dan membandingkannya, sebagai ilustrasi cara melakukannya. Karena NSNumberobjek menerapkan metode perbandingan, itu bisa ditulis ulang jauh lebih sederhana:

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

atau badan pembanding bahkan bisa disuling menjadi 1 baris:

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

Saya cenderung lebih suka pernyataan sederhana dan banyak variabel sementara karena kodenya lebih mudah dibaca, dan lebih mudah di-debug. Kompiler mengoptimalkan variabel sementara, jadi tidak ada keuntungan untuk versi all-in-one-line.

Dinesh_
sumber
5

Saya telah membuat perpustakaan kecil metode kategori, yang disebut Linq to ObjectiveC , yang membuat hal semacam ini lebih mudah. Menggunakan metode pengurutan dengan pemilih kunci, Anda dapat mengurutkan birthDatesebagai berikut:

NSArray* sortedByBirthDate = [input sort:^id(id person) {
    return [person birthDate];
}]
ColinE
sumber
Anda harus menyebutnya " LINQ to Objective-C ".
Peter Mortensen
5

Saya baru saja melakukan penyortiran multi level berdasarkan kebutuhan khusus.

// sortir nilainya

    [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

Boobalan
sumber
5

Saya telah menggunakan sortUsingFunction :: di beberapa proyek saya:

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];
roocell
sumber
5

Anda menggunakan NSSortDescriptor untuk mengurutkan NSMutableArray dengan objek kustom

 NSSortDescriptor *sortingDescriptor;
 sortingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                       ascending:YES];
 NSArray *sortArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];
Arvind Patel
sumber
4
-(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted 
{
  NSArray *sortedArray;
  sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 
  {
    return [a compare:b];
 }];
 return [sortedArray mutableCopy];
}
Emile Khattar
sumber
mengapa harus lulus dalam array yang bisa berubah, ketika array baru dikembalikan. mengapa membuat pembungkus sama sekali?
vikingosegundo
3

Penyortiran NSMutableArraysangat sederhana:

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];
Mohit
sumber
2

Sortir menggunakan NSComparator

Jika kita ingin mengurutkan objek khusus yang perlu kita sediakan NSComparator, yang digunakan untuk membandingkan objek kustom. Blok mengembalikan NSComparisonResultnilai untuk menunjukkan urutan dua objek. Jadi untuk mengurutkan seluruh array NSComparatordigunakan dengan cara berikut.

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

Mengurutkan Menggunakan NSSortDescriptor
Mari kita asumsikan, sebagai contoh, bahwa kita memiliki array yang berisi instance dari kelas kustom, Karyawan memiliki atribut firstname, lastname, dan age. Contoh berikut menggambarkan cara membuat NSSortDescriptor yang dapat digunakan untuk mengurutkan konten array dalam urutan menaik dengan kunci usia.

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

Mengurutkan menggunakan Perbandingan Kustom
Nama adalah string, dan ketika Anda mengurutkan string untuk disajikan kepada pengguna, Anda harus selalu menggunakan perbandingan yang dilokalkan. Seringkali Anda juga ingin melakukan perbandingan kasus yang tidak sensitif. Inilah contoh dengan (localizedStandardCompare :) untuk memesan array dengan nama belakang dan nama depan.

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

Untuk referensi dan diskusi terperinci silakan merujuk: 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 /

Aamir
sumber
1

Protokol dan pemrograman fungsional Swift membuatnya sangat mudah, Anda hanya perlu membuat kelas Anda sesuai dengan protokol Sebanding, mengimplementasikan metode yang diperlukan oleh protokol dan kemudian menggunakan fungsi urutan tinggi (oleh:) untuk membuat array yang diurutkan tanpa perlu menggunakan array bisa berubah dengan cara.

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)
James Rochabrun
sumber
1

Dalam kasus saya, saya menggunakan "sortArrayUsingComparator" untuk mengurutkan array. Lihatlah kode di bawah ini.

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

Juga objek saya adalah,

@interface ContactListData : JsonData
@property(nonatomic,strong) NSString * contactName;
@property(nonatomic,strong) NSString * contactSurname;
@property(nonatomic,strong) NSString * contactPhoneNumber;
@property(nonatomic) BOOL isSelected;
@end
Emre Gürses
sumber
1

Anda harus membuat sortDescriptor dan kemudian Anda dapat mengurutkan nsmutablearray dengan menggunakan sortDescriptor seperti di bawah ini.

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

Gunakan seperti ini untuk objek bersarang,

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

lastRoute adalah satu objek dan objek itu memegang objek to, objek yang memegang nilai string nama belakang.

Sureshkumar Linganathan
sumber
0

Sortir Array Dalam Swift


Untuk SwiftyOrang di bawah ini adalah teknik yang sangat bersih untuk mencapai tujuan di atas secara global. Mari kita memiliki contoh kelas khusus Useryang memiliki beberapa atribut.

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

Sekarang kita memiliki array yang perlu kita sortir berdasarkan createdDatenaik dan / atau turun. Jadi mari kita tambahkan fungsi untuk perbandingan tanggal.

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

Sekarang mari kita memiliki extensiondari Arrayuntuk User. Dengan kata sederhana, mari kita tambahkan beberapa metode hanya untuk Array yang hanya memiliki Userobjek di dalamnya.

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

Penggunaan untuk Ascending Order

let sortedArray = someArray.sortUserByDate(.orderedAscending)

Penggunaan untuk Pesanan Menurun

let sortedArray = someArray.sortUserByDate(.orderedAscending)

Penggunaan untuk Pesanan yang Sama

let sortedArray = someArray.sortUserByDate(.orderedSame)

Metode di atas extensionhanya akan dapat diakses jika Arraybertipe [User]||Array<User>

Syed Qamar Abbas
sumber
0

Versi cepat: 5.1

Jika Anda memiliki struct atau kelas kustom dan ingin mengurutkannya secara sewenang-wenang, Anda harus memanggil sort () menggunakan trailing closure yang mengurutkan pada bidang yang Anda tentukan. Berikut ini contoh menggunakan array struct khusus yang mengurutkan pada properti tertentu:

    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
    }

Jika Anda ingin mengembalikan array yang diurutkan daripada mengurutkannya, gunakan sortir () seperti ini:

    let sortedUsers = users.sorted {
        $0.firstName < $1.firstName
    }
sDev
sumber
0
  let sortedUsers = users.sorted {
    $0.firstName < $1.firstName
 }
manishkumar
sumber
Pertanyaannya adalah tentang NSMutableArray, bukan tentang koleksi Array di Swift
Ricardo
-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(@"===============================");
Siddhesh Bondre
sumber