为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用自定义对象对NSMutableArray进行排序?

如何使用自定义对象对NSMutableArray进行排序?

iOS
婷婷同学_ 2019-05-27 15:07:50
如何使用自定义对象对NSMutableArray进行排序?我想做的事情似乎很简单,但我在网上找不到任何答案。我有一个NSMutableArray对象,让我们说它们是'人'对象。我想NSMutableArray按Person.birthDate 排序,这是一个NSDate。我认为这与这个方法有关:NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(???)];在Java中,我会使我的对象实现Comparable,或者使用带有内联自定义比较器的Collections.sort ...你到底如何在Objective-C中执行此操作?
查看完整描述

4 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

比较方法

要么为对象实现compare方法:

- (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作为后者依赖于KVC。该NSSortDescriptor方法的主要优点是它提供了一种使用数据而不是代码来定义排序顺序的方法,这使得设置起来很容易,因此用户可以NSTableView通过单击标题行来对其进行排序。


查看完整回答
反对 回复 2019-05-27
?
HUX布斯

TA贡献1876条经验 获得超6个赞

NSMutableArray方法sortUsingFunction:context:

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

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

此函数返回NSComparisonResultNSOrderedAscending如果PersonA.birthDate< ,则返回PersonB.birthDateNSOrderedDescending如果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;}

如果你这么做的话,内联也许可以加快一点。


查看完整回答
反对 回复 2019-05-27
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

我在iOS 4中使用块来完成此操作。不得不将我的数组元素从id转换为我的类类型。在这种情况下,它是一个名为Score的类,其中包含一个名为points的属性。

如果数组的元素不是正确的类型,你还需要决定该怎么做,这个例子我刚刚返回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:这是按降序排序。


查看完整回答
反对 回复 2019-05-27
?
月关宝盒

TA贡献1772条经验 获得超5个赞

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

注意:“已排序”数组将自动释放。



查看完整回答
反对 回复 2019-05-27
  • 4 回答
  • 0 关注
  • 927 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信