Як сортувати NSMutableArray зі спеціальними об'єктами в ньому?


1268

Те, що я хочу зробити, здається досить простим, але я не можу знайти жодної відповіді в Інтернеті. У мене єNSMutableArray об'єкти, і скажімо, що це "особи". Я хочу сортувати NSMutableArrayпо Person.birthDate, який є NSDate.

Я думаю, що це стосується цього методу:

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

У Java я би змусив мій об’єкт реалізувати Порівняно, або використовувати Collections.sort з вбудованим спеціальним компаратором ... як на землі це робити в Objective-C?

Відповіді:


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

Ви можете легко сортувати за кількома клавішами, додавши до масиву декілька. Можливе також використання спеціальних методів порівняння. Погляньте на документацію .

Блоки (блискучі!)

Існує також можливість сортування за допомогою блоку з Mac OS X 10.6 та 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];
}];

Продуктивність

-compare:І блокові методи на основі буде зовсім небагато швидше, в загальному, ніж при використанні в NSSortDescriptorякості останнього покладається на КВЦ. Основна перевага NSSortDescriptorметоду полягає в тому, що він забезпечує спосіб визначення порядку сортування за допомогою даних, а не коду, що полегшує, наприклад, налаштування речей, щоб користувачі могли сортувати NSTableView, натискаючи на рядок заголовка.


66
Перший приклад містить помилку: ви порівнюєте змінну екземпляра birthDate в одному об'єкті з самим іншим об'єктом, а не його змінною birthDate.
Мартін Гяльдбек

90
@Martin: Дякую! Смішно, що ще ніхто не помітив, перш ніж я отримав 75 ​​оновлень.
Георг Шоллі

76
Оскільки це прийнята відповідь, і тому, ймовірно, вважається остаточною більшістю користувачів, може бути корисним додати третій, блок-приклад, щоб користувачі усвідомлювали, що він теж існує.
jpswain

6
@ orange80: Я спробував це. Я більше не володію Mac, тому було б добре, якби ви подивилися на код.
Георг Шоллі

11
Якщо у вас є, NSMutableArrayя вважаю за краще використовувати методи sortUsingDescriptors, sortUsingFunctionабо sortUsingSelector. Наскільки масив є змінним, мені зазвичай не потрібна сортована копія.
Стефан

109

Дивіться NSMutableArrayметодsortUsingFunction:context:

Вам потрібно буде встановити функцію порівняння, яка бере два об'єкти (типу Person, оскільки ви порівнюєте два Personоб'єкти) та контекстний параметр.

Два об'єкти - це лише екземпляри Person. Третій об’єкт - рядок, наприклад @ "BirthDate".

Ця функція повертає 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;
}

Вкладиш може, можливо, трохи прискорити це, якщо ви зробите це багато.


9
Використання sortUsingFunction: context: це, мабуть, самий c-ish спосіб і, безумовно, самий нечитабельний.
Георг Шьолі

12
З цим нічого поганого немає, але я думаю, що зараз є набагато кращі альтернативи.
Георг Шоллі

6
Можливо, але я не думаю, що це було б не менш читабельним для когось із Java-колективу, який, можливо, шукає щось подібне до абстрактного Java-класу Comparator, який реалізує порівняння (Type obj1, Type obj2).
Алекс Рейнольдс

5
Я розумію, що пара з вас шукає будь-якої причини критикувати цю ідеально чудову відповідь, навіть якщо ця критика має дуже мало технічних достоїнств. Дивно.
Алекс Рейнольдс

1
@Yar: Або ви можете використовувати рішення, яке я запропонував у першому пункті, або ви використовуєте кілька дескрипторів сортування. sortedArrayUsingDescriptors: приймає масив дескрипторів сортування як аргумент.
Георг Шоллі

62

Я робив це в iOS 4 за допомогою блоку. Довелося передати елементи мого масиву з id до типу мого класу. У цьому випадку це був клас під назвою Score із властивістю під назвою точки.

Також вам потрібно вирішити, що робити, якщо елементи вашого масиву не є правильним типом, для цього прикладу я щойно повернувся 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: Це сортування у порядку зменшення.


6
Насправді вам не потрібні кадри "(Score *)", ви можете просто зробити "Score * s1 = obj1;" тому що ідентифікатор буде щасливий на будь-що, без попередження компілятора :-)
jpswain

Праворуч80 downcastingне вимагає вступу перед слабкою змінною.
підписання

Ви повинні сортувати "нуль" проти "нуля" до верху чи внизу послідовно, тому кінцеве повернення за замовчуванням може бутиreturn ((!obj1 && !obj2) ? NSOrderedSame : (obj1 ? NSOrderedAscending : NSOrderedDescending))
Скотт Корскадден

Хе, Кріс, я спробував цей код, я ввімкнув оновлення у своїй програмі .. вперше я правильно виконую роботу, отримав вихідний порядок виходу .., але коли я оновив. (виконаю той самий код з тими ж даними), він змінився порядок, він не спадав .. Скажіть, я hv 4 об’єкти в моєму масиві, 3 hv ті ж дані, 1 відрізняється.
Nikesh K

Якщо ви насправді очікуєте об’єктів, які не належать до класу "Оцінка", вам потрібно сортувати їх трохи ретельніше. В іншому випадку у вас виникає ситуація, коли інше == score1 <score2 == інше, що є непослідовним і може призвести до проблем. Ви можете повернути значення, яке передбачає сортування об'єктів сортування перед усіма іншими об'єктами, а всі інші об'єкти впорядковують однакові.
gnasher729

29

Починаючи з iOS 4, ви також можете використовувати блоки для сортування.

У цьому конкретному прикладі я припускаю, що об’єкти у вашому масиві мають метод 'position', який повертає 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', тому що був витрачений час, коли я скопіював і вставив, і він не вдався без 's' у sortedArrayUsingDescriptors


Виклик методу насправді "sortedArrayUsingDescriptors:", з 's' в кінці.
CIFilter

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 відповідно до відносин між двома об'єктами.

Тоді ви могли б назвати sortedArrayUsingSelector:з@selector(compare:) , і це повинно бути зроблено.

Є й інші способи, але, наскільки я знаю, немає інтервалу какао-інтервалу Comparable. Використання sortedArrayUsingSelector:, мабуть, найбільш безболісний спосіб це зробити.


9

iOS 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методу. Він сортує це місце, не створюючи нового примірника.


Просто оновлення: я теж шукав щось, що сортувало мінливий масив на місці, зараз є "сортування" використання еквівалентних методів для всіх методів "sortedArrayUsing" на iOS 7. Таких як sortUsingComparator:.
jmathew

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 об’єктів або навіть для масиву спеціальних об'єктів даних, які реалізують метод порівняння.

Ось кілька прикладів коду за допомогою блоків порівняння. Він сортує масив словників, де кожен словник включає номер у ключі "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;
 }];

Код, описаний вище, проходить через отримання цілого значення для кожного ключа сортування та порівняння їх, як ілюстрацію того, як це зробити. Оскільки 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

Я створив невелику бібліотеку методів категорій, що називається Linq to ObjectiveC , що полегшує подібні речі. Використовуючи метод сортування за допомогою селектора ключів, ви можете сортувати 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

Ви використовуєте NSSortDescriptor для сортування NSMutableArray зі спеціальними об'єктами

 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
Припустимо, як приклад, що у нас є масив, що містить екземпляри спеціального класу, Employee має атрибути ім'я, прізвище та вік. Наступний приклад ілюструє, як створити 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 / aim-c / how to sorte-nsarray-with-custom-objects /


1

Протоколи та функціональне програмування Swift робить це дуже просто, вам просто потрібно зробити свій клас відповідним порівнянному протоколу, реалізувати методи, необхідні протоколом, а потім використовувати відсортовану (за:) функцію високого порядку для створення відсортованого масиву без необхідності використання до речі змінні масиви.

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, а потім ви можете сортувати nsmutablearray, використовуючи sortDescriptor, як показано нижче.

 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 - це один об'єкт, і цей об'єкт утримує об'єкт, який об'єктом містить значення рядка прізвища.


0

Сортувати масив у Swift


Для 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

Якщо у вас є власна структура або клас і хочете сортувати їх довільно, вам слід зателефонувати sort (), використовуючи трейлінг-закриття, яке сортує у вказаному вами полі. Ось приклад використання масиву користувацьких структур, які сортують певну властивість:

    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
    }

Якщо ви хочете повернути відсортований масив, а не сортувати його на місці, використовуйте sorted () таким чином:

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


-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 та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.