我想做的事情似乎很简单,但我在网上找不到任何答案。我有一个对象的NSMutableArray,假设它们是Person对象。我想对NSMutableArray按Person排序。birthDate是一个NSDate。

我认为这与这个方法有关:

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

在Java中,我将使我的对象实现Comparable,或使用集合。使用内联自定义比较器排序…在Objective-C中怎么做呢?


当前回答

-(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted 
{
  NSArray *sortedArray;
  sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 
  {
    return [a compare:b];
 }];
 return [sortedArray mutableCopy];
}

其他回答

参见NSMutableArray方法sortUsingFunction:context:

您将需要设置一个compare函数,该函数接受两个对象(类型为Person,因为您正在比较两个Person对象)和一个上下文参数。

这两个对象只是Person的实例。第三个对象是字符串,例如@"birthDate"。

这个函数返回一个NSComparisonResult:如果是PersonA,则返回NSOrderedAscending。birthDate < person .birthDate。它将返回nsordereddescent如果PersonA。person .birthDate。最后,它将返回NSOrderedSame如果PersonA。birthDate == person .birthDate。

这是粗略的伪代码;你需要充实一个日期“更少”、“更多”或“等于”另一个日期的含义(比如比较从epoch开始的秒数等):

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

内联可能会加快这一点,如果你这样做了很多。

在我的例子中,我使用“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

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

注意:排序后的数组将被自动释放。

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

您可以使用以下通用方法来实现您的目的。这应该能解决你的问题。

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