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

前端 未结 27 3242
予麋鹿
予麋鹿 2020-11-21 04:45

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

相关标签:
27条回答
  • 2020-11-21 05:17

    You use NSSortDescriptor to sort an NSMutableArray with custom objects

     NSSortDescriptor *sortingDescriptor;
     sortingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                           ascending:YES];
     NSArray *sortArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];
    
    0 讨论(0)
  • 2020-11-21 05:18

    In my case, I use "sortedArrayUsingComparator" to sort an array. 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
    
    0 讨论(0)
  • 2020-11-21 05:18

    Sort Array In Swift


    For Swifty Person below is a very clean technique to achieve above goal for globally. Lets have an example custom class of User which have some attributes.

    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. 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. In simple words lets add some methods only for those Array's which only have User objects in it.

    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>

    0 讨论(0)
  • 2020-11-21 05:21

    If you're just sorting an array of NSNumbers, you can sort them with 1 call:

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

    That works because the objects in the array (NSNumber objects) implement the compare method. You could do the same thing for NSString objects, or even for an array of custom data objects that implement a compare method.

    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".

    #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:

     #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:

      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.

    0 讨论(0)
  • 2020-11-21 05:22

    iOS 4 blocks will save you :)

    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

    0 讨论(0)
  • 2020-11-21 05:23

    I have created a small library of category methods, called Linq to ObjectiveC, that makes this sort of thing more easy. Using the sort method with a key selector, you can sort by birthDate as follows:

    NSArray* sortedByBirthDate = [input sort:^id(id person) {
        return [person birthDate];
    }]
    
    0 讨论(0)
提交回复
热议问题