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

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

提问人:rustyshelf 提问时间:4/30/2009 最后编辑:Peter Mortensenrustyshelf 更新时间:6/7/2021 访问量:485104

问:

我想做的事情看起来很简单,但我在网上找不到任何答案。我有一个对象,假设它们是“人”对象。我想按 Person.birthDate 排序,这是一个 .NSMutableArrayNSMutableArrayNSDate

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

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

在 Java 中,我会让我的对象实现 Comparable,或者将 Collections.sort 与内联自定义比较器一起使用......在Objective-C中,你到底是怎么做到的?

iOS Objective-C 排序 Cocoa-Touch nsmutableArray

评论


答:

19赞 freespace 4/30/2009 #1

你的对象需要实现一个方法,比如说哪个对象接受另一个对象,并根据两个对象之间的关系返回。Personcompare:PersonNSComparisonResult

然后你会打电话,它应该完成。sortedArrayUsingSelector:@selector(compare:)

还有其他方法,但据我所知,界面没有 Cocoa-equiv。使用可能是最轻松的方法。ComparablesortedArrayUsingSelector:

113赞 Alex Reynolds 4/30/2009 #2

参见 sortUsingFunction:context 方法:NSMutableArray

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

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

此函数返回一个 : 如果 < ,则返回 。如果>,它将返回。最后,它将返回 if == 。NSComparisonResultNSOrderedAscendingPersonA.birthDatePersonB.birthDateNSOrderedDescendingPersonA.birthDatePersonB.birthDateNSOrderedSamePersonA.birthDatePersonB.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;
}

如果你经常这样做,内联也许可以加快一点速度。

评论

9赞 Georg Schölly 4/30/2009
使用 sortUsingFunction:context: 可能是最简单的方法,也绝对是最不可读的方法。
12赞 Georg Schölly 4/30/2009
这并没有真正的问题,但我认为现在有更好的选择。
6赞 Alex Reynolds 4/30/2009
也许吧,但我认为对于来自 Java 背景的人来说,它的可读性不会降低,他们可能正在寻找类似于 Java 的抽象 Comparator 类的东西,该类实现了 compare(Type obj1, Type obj2)。
5赞 Alex Reynolds 5/2/2009
我感觉到你们中的一些人正在寻找任何理由来批评这个完美的答案,即使这种批评几乎没有技术价值。奇怪。
1赞 Georg Schölly 12/17/2010
@Yar:您可以使用我在第一段中提供的解决方案,也可以使用多个排序描述符。sortedArrayUsingDescriptors:将排序描述符数组作为参数。
2347赞 17 revs, 10 users 72%Georg Schölly #3

Compare 方法

要么为对象实现 compare-method:

- (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(Person *a, Person *b) {
    return [a.birthDate compare:b.birthDate];
}];

性能

一般来说,基于块的方法会比使用的方法快得多,因为后者依赖于 KVC。该方法的主要优点是它提供了一种使用数据而不是代码定义排序顺序的方法,这使得例如设置内容变得容易,以便用户可以通过单击标题行进行排序。-compare:NSSortDescriptorNSSortDescriptorNSTableView

评论

69赞 Martin Gjaldbaek 5/17/2011
第一个示例有一个错误:将一个对象中的 birthDate 实例变量与另一个对象本身进行比较,而不是将 birthDate 变量进行比较。
93赞 Georg Schölly 5/17/2011
@Martin:谢谢!有趣的是,在我获得 75 个赞成票之前,没有人注意到它。
79赞 jpswain 12/3/2011
因为这是公认的答案,因此可能被大多数用户认为是确定的,所以添加第三个基于块的示例可能会有所帮助,以便用户也知道它的存在。
6赞 Georg Schölly 12/5/2011
@orange80:我试过了。我不再拥有 Mac,所以如果你能看看代码就好了。
11赞 Stephan 8/6/2012
如果您有我更喜欢使用方法,或者.就数组是可变的而言,我通常不需要排序的副本。NSMutableArraysortUsingDescriptorssortUsingFunctionsortUsingSelector
28赞 Manuel Spuhler 5/7/2009 #4

Georg Schölly 的第二个答案中缺少一个步骤,但效果很好。

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

添加了“s”,因为我在复制和粘贴时浪费了时间,并且在sortedArrayUsingDescriptors中没有“s”的情况下失败了

评论

0赞 CIFilter 5/14/2009
方法调用实际上是“sortedArrayUsingDescriptors:”,末尾有一个“s”。
10赞 DenTheMan 11/9/2010 #5

对于 ,请使用该方法。它对 it-place 进行排序,而不创建新实例。NSMutableArraysortUsingSelector

评论

0赞 jmathew 11/18/2013
只是一个更新:我也在寻找对可变数组进行排序的东西,现在从 iOS 7 开始,所有“sortedArrayUsing”方法都有“sortUsing”等效方法。如。sortUsingComparator:
31赞 Fernando Redondo 11/22/2010 #6

我尝试了所有方法,但这对我有用。在一个类中,我有另一个名为“”的类,并希望按“”的属性进行排序。crimeScenecrimeScene

这就像一个魅力:

NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"crimeScene.distance" ascending:YES];
[self.arrAnnotations sortUsingDescriptors:[NSArray arrayWithObject:sorter]];
30赞 leviathan 3/17/2011 #7

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

注意:“sorted”数组将自动释放。

66赞 Chris 3/25/2011 #8

我在 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:这是按降序排序的。

评论

7赞 jpswain 12/3/2011
你实际上并不需要“(Score *)”转换,你可以只做“Score *s1 = obj1;”,因为id会很乐意转换到任何内容,而不会得到编译器的警告:-)
0赞 geekay 5/3/2012
右 orange80 不需要在弱变量之前进行强制转换。downcasting
0赞 Scott Corscadden 8/9/2012
您应该始终如一地将 nil 与 not-nil 排序到顶部或底部,因此默认的结束返回可能是return ((!obj1 && !obj2) ? NSOrderedSame : (obj1 ? NSOrderedAscending : NSOrderedDescending))
0赞 Nikesh K 9/13/2012
呵呵,克里斯,我尝试了这段代码,我在我的程序中进行了更新。.我第一次做正确的工作,得到一个降序输出。.但是当我刷新时。(用相同的数据执行相同的代码)它改变了顺序,它没有降序。假设我的数组中有 4 个对象,3 个 hv 相同的数据,1 个是不同的。
0赞 gnasher729 2/17/2014
如果您实际上期望不属于“Score”类的对象,则需要更仔细地对它们进行排序。否则,您会遇到其他 == score1 < score2 == other 不一致的情况,这可能会导致麻烦。您可以返回一个值,该值表示 Score 对象在所有其他对象之前排序,并且所有其他对象之间的排序相等。
21赞 Hardik Darji 3/30/2011 #9
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];

谢谢,它工作正常...

12赞 2 revs, 2 users 70%Kostiantyn Sokolinskyi #10

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

7赞 roocell 5/9/2011 #11

我在我的一些项目中使用了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];
5赞 Mohit 9/6/2011 #12

排序非常简单: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];
8赞 Dinesh_ 12/6/2012 #13

如果您只是对 的数组进行排序,则可以使用 1 次调用对它们进行排序:NSNumbers

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

这之所以有效,是因为数组中的对象 ( objects) 实现了 compare 方法。您可以对对象执行相同的操作,甚至可以对实现比较方法的自定义数据对象数组执行相同的操作。NSNumberNSString

下面是一些使用比较器模块的示例代码。它对字典数组进行排序,其中每个字典在键“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;
 }];

上面的代码介绍了获取每个排序键的整数值并进行比较的工作,以说明如何做到这一点。由于对象实现了 compare 方法,因此可以更简单地重写它: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];
 }];

或者比较器的主体甚至可以提炼成 1 行:

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

我倾向于使用简单的语句和大量的临时变量,因为代码更易于阅读和调试。无论如何,编译器都会优化掉临时变量,因此多合一版本没有任何优势。

7赞 Emile Khattar 1/10/2013 #14
-(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted 
{
  NSArray *sortedArray;
  sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 
  {
    return [a compare:b];
 }];
 return [sortedArray mutableCopy];
}

评论

0赞 vikingosegundo 1/10/2013
为什么在返回新数组时传入可变数组。为什么要创建一个包装器?
7赞 ColinE 3/6/2013 #15

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

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

评论

0赞 Peter Mortensen 11/28/2017
您应该称它为“LINQ to Objective-C”。
7赞 Boobalan 6/4/2013 #16

我刚刚根据自定义要求进行了多级排序。

对值进行排序

    [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

-2赞 2 revs, 2 users 81%Siddhesh Bondre #17
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(@"===============================");
9赞 MD Aslam Ansari 4/16/2015 #18

您可以根据自己的目的使用以下通用方法。它应该可以解决您的问题。

//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];
5赞 Aamir 6/16/2016 #19

使用 NSComparator 进行排序

如果我们想对自定义对象进行排序,我们需要提供 ,用于比较自定义对象。该块返回一个值来表示两个对象的顺序。因此,为了对整个数组进行排序,以下方式使用。NSComparatorNSComparisonResultNSComparator

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

使用 NSSortDescriptor
进行排序 举个例子,假设我们有一个包含自定义类实例的数组,Employee 具有属性 firstname、lastname 和 age。下面的示例演示如何创建一个 NSSortDescriptor,该描述符可用于按年龄键按升序对数组内容进行排序。

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

使用自定义比较进行排序 名称是字符串,在对字符串进行排序以呈现给用户时,应始终使用本地化比较
。通常,您还希望执行不区分大小写的比较。下面是一个示例,其中包含 (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];

有关参考和详细讨论,请参阅: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/

3赞 Emre Gürses 12/13/2016 #20

就我而言,我使用“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
4赞 James Rochabrun 3/28/2017 #21

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)
2赞 Syed Qamar Abbas 3/25/2018 #22

在 Swift 中对数组进行排序


对于以下人员来说,这是一项非常干净的技术,可以在全球范围内实现上述目标。让我们有一个示例自定义类,该类具有一些属性。SwiftyUser

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

现在让我们有一个 of .简而言之,让我们只为那些只有对象的数组添加一些方法。extensionArrayUserUser

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)

上述方法 in 只有在 类型为 ||extensionArray[User]Array<User>

3赞 Parth Barot 4/12/2018 #23

您必须创建 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)
8赞 Arvind Patel 6/14/2018 #24

使用 NSSortDescriptor 对具有自定义对象的 NSMutableArray 进行排序

 NSSortDescriptor *sortingDescriptor;
 sortingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                       ascending:YES];
 NSArray *sortArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];
2赞 Sureshkumar Linganathan 4/24/2019 #25

像这样用于嵌套对象,

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

lastRoute 是一个对象,该对象保存 to 对象,to 对象保存 lastname 字符串值。

2赞 sDev 2/20/2020 #26

Swift版本:5.1

如果您有自定义结构或类并希望对它们进行任意排序,则应使用尾随闭包调用 sort(),该闭包对指定的字段进行排序。下面是一个示例,使用对特定属性进行排序的自定义结构数组:

    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
    }

如果你想返回一个排序的数组,而不是就地排序,请使用sorted(),如下所示:

    let sortedUsers = users.sorted {
        $0.firstName < $1.firstName
    }
2赞 Manish Kumar 3/16/2020 #27
  let sortedUsers = users.sorted {
    $0.firstName < $1.firstName
 }

评论

0赞 Ricardo 5/17/2020
问题是关于 NSMutableArray,而不是关于 Swift 中的 Arrays 集合