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

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

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

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


当前回答

Swift中的数组排序


对于Swifty Person来说,下面是一个非常干净的技术,可以在全球范围内实现上述目标。让我们有一个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
    }
}

现在让我们有一个扩展数组为用户。简单地说,让我们为那些只有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)

只有当数组为类型时,上述扩展方法才可访问 [User] || Array<用户> .使用实例

其他回答

你的Person对象需要实现一个方法,比如compare:它接受另一个Person对象,并根据两个对象之间的关系返回NSComparisonResult。

然后你会调用sortedArrayUsingSelector: with @selector(compare:),这应该就完成了。

还有其他方法,但据我所知,还没有类似可比性接口的cocoa。使用sortedArrayUsingSelector:可能是最简单的方法。

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

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

我已经创建了一个小型的类别方法库,称为Linq to ObjectiveC,这使得这类事情更加容易。使用带有键选择器的sort方法,您可以按birthDate进行排序,如下所示:

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

我什么都试过了,但这个对我有用。在一个类中,我有另一个名为“crimeScene”的类,并希望通过“crimeScene”的属性进行排序。

这就像一个魅力:

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

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一点描述