简体   繁体   English

如何对包含自定义对象的 NSMutableArray 进行排序?

[英]How do I sort an NSMutableArray with custom objects in it?

What I want to do seems pretty simple, but I can't find any answers on the web.我想做的事情看起来很简单,但我在网上找不到任何答案。 I have an NSMutableArray of objects, and let's say they are 'Person' objects.我有一个NSMutableArray对象,假设它们是“人”对象。 I want to sort the NSMutableArray by Person.birthDate which is an NSDate .我想通过 Person.birthDate 对NSMutableArray进行排序,它是一个NSDate

I think it has something to do with this method:我认为这与这种方法有关:

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

In Java I would make my object implement Comparable, or use Collections.sort with an inline custom comparator...how on earth do you do this in Objective-C?在 Java 中,我会让我的对象实现 Comparable,或者将 Collections.sort 与内联自定义比较器一起使用……你到底是如何在 Objective-C 中做到这一点的?

Compare method比较方法

Either you implement a compare-method for your object:要么为对象实现比较方法:

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

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

NSSortDescriptor (better) NSSortDescriptor(更好)

or usually even better:或者通常更好:

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

You can easily sort by multiple keys by adding more than one to the array.您可以通过向数组添加多个键来轻松地按多个键排序。 Using custom comparator-methods is possible as well.也可以使用自定义比较器方法。 Have a look at the documentation .查看文档

Blocks (shiny!)块(闪亮!)

There's also the possibility of sorting with a block since Mac OS X 10.6 and iOS 4:自 Mac OS X 10.6 和 iOS 4 起,还可以使用块进行排序:

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

Performance表现

The -compare: and block-based methods will be quite a bit faster, in general, than using NSSortDescriptor as the latter relies on KVC. -compare:和基于块的方法通常比使用NSSortDescriptor快得多,因为后者依赖于 KVC。 The primary advantage of the NSSortDescriptor method is that it provides a way to define your sort order using data, rather than code, which makes it easy to eg set things up so users can sort an NSTableView by clicking on the header row. NSSortDescriptor方法的主要优点是它提供了一种使用数据而不是代码来定义排序顺序的方法,这使得设置变得容易,例如,用户可以通过单击标题行对NSTableView进行排序。

See the NSMutableArray method sortUsingFunction:context:参见NSMutableArray方法sortUsingFunction:context:

You will need to set up a compare function which takes two objects (of type Person , since you are comparing two Person objects) and a context parameter.您将需要设置一个比较函数,它接受两个对象(类型为Person ,因为您正在比较两个Person对象)和一个上下文参数。

The two objects are just instances of Person .这两个对象只是Person实例。 The third object is a string, eg @"birthDate".第三个对象是一个字符串,例如@"birthDate"。

This function returns an NSComparisonResult : It returns NSOrderedAscending if PersonA.birthDate < PersonB.birthDate .这个函数返回一个NSComparisonResult :它返回NSOrderedAscending如果PersonA.birthDate < PersonB.birthDate It will return NSOrderedDescending if PersonA.birthDate > PersonB.birthDate .它将返回NSOrderedDescending如果PersonA.birthDate > PersonB.birthDate Finally, it will return NSOrderedSame if PersonA.birthDate == PersonB.birthDate .最后,它会返回NSOrderedSame如果PersonA.birthDate == PersonB.birthDate

This is rough pseudocode;这是粗略的伪代码; you will need to flesh out what it means for one date to be "less", "more" or "equal" to another date (such as comparing seconds-since-epoch etc.):您需要详细说明一个日期与另一个日期“更少”、“更多”或“相等”的含义(例如比较自纪元以来的秒数等):

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

If you want something more compact, you can use ternary operators:如果你想要更紧凑的东西,你可以使用三元运算符:

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

Inlining could perhaps speed this up a little, if you do this a lot.如果您经常这样做,内联可能会加快速度。

I did this in iOS 4 using a block.我在 iOS 4 中使用块完成了此操作。 Had to cast the elements of my array from id to my class type.必须将我的数组元素从 id 转换为我的类类型。 In this case it was a class called Score with a property called points.在本例中,它是一个名为 Score 的类,具有一个名为 points 的属性。

Also you need to decide what to do if the elements of your array are not the right type, for this example I just returned NSOrderedSame , however in my code I though an exception.此外,您还需要决定如果数组元素的类型不正确该怎么NSOrderedSame ,在本示例中,我只返回了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: This is sorting in descending order. PS:这是降序排列。

I tried all, but this worked for me.我尝试了所有,但这对我有用。 In a class I have another class named " crimeScene ", and want to sort by a property of " crimeScene ".在一个类中,我有另一个名为“ crimeScene ”的类,并且想要按“ crimeScene ”的属性进行排序。

This works like a charm:这就像一个魅力:

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

Starting in iOS 4 you can also use blocks for sorting.从 iOS 4 开始,您还可以使用块进行排序。

For this particular example I'm assuming that the objects in your array have a 'position' method, which returns an NSInteger .对于这个特定的例子,我假设数组中的对象有一个 '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];

Note: the "sorted" array will be autoreleased.注意:“排序”数组将被自动释放。

There is a missing step in Georg Schölly's second answer , but it works fine then. Georg Schölly 的第二个答案中缺少一个步骤,但它可以正常工作。

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

// added the 's' because time was wasted when I copied and pasted and it failed without the 's' in sortedArrayUsingDescriptors // 添加了 's' 因为当我复制和粘贴时浪费了时间,并且在 sortedArrayUsingDescriptors 中没有 's' 失败

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

Thanks, it's working fine...谢谢,它工作正常...

Your Person objects need to implement a method, say compare: which takes another Person object, and return NSComparisonResult according to the relationship between the 2 objects.你的Person对象需要实现一个方法,比如compare:它接受另一个Person对象,并根据两个对象之间的关系返回NSComparisonResult

Then you would call sortedArrayUsingSelector: with @selector(compare:) and it should be done.然后你会用@selector(compare:)调用sortedArrayUsingSelector:它应该完成。

There are other ways, but as far as I know there is no Cocoa-equiv of the Comparable interface.还有其他方法,但据我所知, Comparable接口没有 Cocoa-equiv。 Using sortedArrayUsingSelector: is probably the most painless way to do it.使用sortedArrayUsingSelector:可能是最sortedArrayUsingSelector:方法。

iOS 4 blocks will save you :) 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 a bit of description http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html一些描述

For NSMutableArray , use the sortUsingSelector method.对于NSMutableArray ,使用sortUsingSelector方法。 It sorts it-place, without creating a new instance.它就地排序,无需创建新实例。

You can use the following generic method for your purpose.您可以根据自己的目的使用以下通用方法。 It should solve your issue.它应该可以解决您的问题。

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

If you're just sorting an array of NSNumbers , you can sort them with 1 call:如果您只是对NSNumbers数组进行排序,则可以通过 1 次调用对它们进行排序:

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

That works because the objects in the array ( NSNumber objects) implement the compare method.这是因为数组中的对象( NSNumber对象)实现了 compare 方法。 You could do the same thing for NSString objects, or even for an array of custom data objects that implement a compare method.您可以对NSString对象执行相同的操作,甚至可以对实现比较方法的自定义数据对象数组执行相同的操作。

Here's some example code using comparator blocks.下面是一些使用比较器块的示例代码。 It sorts an array of dictionaries where each dictionary includes a number in a key "sort_key".它对字典数组进行排序,其中每个字典在键“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;
 }];

The code above goes through the work of getting an integer value for each sort key and comparing them, as an illustration of how to do it.上面的代码完成了为每个排序键获取整数值并比较它们的工作,作为如何执行此操作的说明。 Since NSNumber objects implement a compare method, it could be rewritten much more simply:由于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];
 }];

or the body of the comparator could even be distilled down to 1 line:或者比较器的主体甚至可以精简到 1 行:

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

I tend to prefer simple statements and lots of temporary variables because the code is easier to read, and easier to debug.我倾向于喜欢简单的语句和大量的临时变量,因为代码更容易阅读,也更容易调试。 The compiler optimizes away the temporary variables anyway, so there is no advantage to the all-in-one-line version.编译器无论如何都会优化掉临时变量,因此一体机版本没有优势。

You use NSSortDescriptor to sort an NSMutableArray with custom objects您使用 NSSortDescriptor 对带有自定义对象的 NSMutableArray 进行排序

 NSSortDescriptor *sortingDescriptor;
 sortingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                       ascending:YES];
 NSArray *sortArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];
-(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted 
{
  NSArray *sortedArray;
  sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 
  {
    return [a compare:b];
 }];
 return [sortedArray mutableCopy];
}

I have created a small library of category methods, called Linq to ObjectiveC , that makes this sort of thing more easy.我创建了一个名为Linq to ObjectiveC的小型类别方法库,它使此类事情变得更加容易。 Using the sort method with a key selector, you can sort by birthDate as follows:使用带有键选择器的sort方法,您可以按birthDate进行排序,如下所示:

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

I just done multi level sorting based on custom requirement.我刚刚根据自定义要求进行了多级排序。

//sort the values //对值进行排序

    [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 https://sites.google.com/site/greateindiaclub/mobil-apps/ios/multilevelsortinginiosobjectivec

I've used sortUsingFunction:: in some of my projects:我在我的一些项目中使用了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];

Sort using NSComparator使用 NSComparator 排序

If we want to sort custom objects we need to provide NSComparator , which is used to compare custom objects.如果我们想对自定义对象进行排序,我们需要提供NSComparator ,用于比较自定义对象。 The block returns an NSComparisonResult value to denote the ordering of the two objects.该块返回一个NSComparisonResult值来表示两个对象的排序。 So in order to sort whole array NSComparator is used in following way.因此,为了对整个数组进行排序, NSComparator使用以下方式。

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

Sorts Using NSSortDescriptor使用 NSSortDescriptor 排序
Let's assume, as an example, that we have an array containing instances of a custom class, Employee has attributes firstname, lastname and age.例如,假设我们有一个包含自定义类实例的数组,Employee 具有属性 firstname、lastname 和 age。 The following example illustrates how to create an NSSortDescriptor that can be used to sort the array contents in ascending order by the age key.下面的例子说明了如何创建一个 NSSortDescriptor,它可以用来按年龄键按升序对数组内容进行排序。

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

Sort using Custom Comparisons使用自定义比较排序
Names are strings, and when you sort strings to present to the user you should always use a localized comparison.名称是字符串,当您对字符串进行排序以呈现给用户时,您应该始终使用本地化比较。 Often you also want to perform a case insensitive comparison.通常,您还希望执行不区分大小写的比较。 Here comes an example with (localizedStandardCompare:) to order the array by last and first name.这是一个使用 (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];

For reference and detailed discussion please refer: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/SortDescriptors/Articles/Creating.html参考和详细讨论请参考: 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/ http://www.ios-blog.co.uk/tutorials/objective-c/how-to-sort-nsarray-with-custom-objects/

Sorting NSMutableArray is very simple: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];

Swift's protocols and functional programming makes that very easy you just have to make your class conform to the Comparable protocol, implement the methods required by the protocol and then use the sorted(by: ) high order function to create a sorted array without need to use mutable arrays by the way. Swift 的协议和函数式编程让这一切变得非常容易,你只需要让你的类符合 Comparable 协议,实现协议所需的方法,然后使用 sorted(by:) 高阶函数来创建一个排序数组,而无需使用顺便说一下,可变数组。

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)

In my case, I use "sortedArrayUsingComparator" to sort an array.就我而言,我使用“sortedArrayUsingComparator”对数组进行排序。 Look at the below code.看看下面的代码。

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

Also my object is,另外我的目的是,

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

You have to create sortDescriptor and then you can sort the nsmutablearray by using sortDescriptor like below.您必须创建 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)

Sort Array In Swift在 Swift 中对数组进行排序


For Swifty Person below is a very clean technique to achieve above goal for globally.对于下面的Swifty Person 来说,这是一种非常干净的技术,可以在全球范围内实现上述目标。 Lets have an example custom class of User which have some attributes.让我们有一个User的示例自定义类,它具有一些属性。

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

Now we have an array which we need to sort on the basis of createdDate either ascending and/or descending.现在我们有一个数组,我们需要根据createdDate升序和/或降序对其进行排序。 So lets add a function for date comparison.因此,让我们添加一个用于日期比较的函数。

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

Now lets have an extension of Array for User .现在让我们为User extension Array In simple words lets add some methods only for those Array's which only have User objects in it.简单来说,让我们只为那些只有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
    }
}

Usage for Ascending Order升序用法

let sortedArray = someArray.sortUserByDate(.orderedAscending)

Usage for Descending Order降序使用

let sortedArray = someArray.sortUserByDate(.orderedAscending)

Usage for Same Order同一订单的用法

let sortedArray = someArray.sortUserByDate(.orderedSame)

Above method in extension will only be accessible if the Array is of type [User] ||仅当Array的类型为[User] || 时才能访问extension上述方法Array<User>

Use like this for nested objects,像这样用于嵌套对象,

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

lastRoute is one object and that object holds the to object, that to object hold the lastname string values. lastRoute 是一个对象,该对象保存 to 对象,to 对象保存姓氏字符串值。

Swift version: 5.1斯威夫特版本:5.1

If you have a custom struct or class and want to sort them arbitrarily, you should call sort() using a trailing closure that sorts on a field you specify.如果你有一个自定义的结构体或类,并且想对它们进行任意排序,你应该使用一个尾随闭包来调用 sort() ,该闭包对你指定的字段进行排序。 Here's an example using an array of custom structs that sorts on a particular property:这是一个使用对特定属性进行排序的自定义结构数组的示例:

    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
    }

If you want to return a sorted array rather than sort it in place, use sorted() like this:如果你想返回一个排序的数组而不是原地排序,使用 sorted() 像这样:

    let sortedUsers = users.sorted {
        $0.firstName < $1.firstName
    }
  let sortedUsers = users.sorted {
    $0.firstName < $1.firstName
 }
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(@"===============================");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM