【问题标题】:How do I sort an NSMutableArray with custom objects in it?如何对包含自定义对象的 NSMutableArray 进行排序?
【发布时间】:2010-10-22 18:38:18
【问题描述】:

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

我觉得跟这个方法有关系:

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

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

【问题讨论】:

    标签: ios objective-c sorting cocoa-touch nsmutablearray


    【解决方案1】:

    比较方法

    要么为你的对象实现一个比较方法:

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

    您可以通过向数组中添加多个键轻松地按多个键排序。也可以使用自定义比较器方法。看看the documentation

    块(闪亮!)

    从 Mac OS X 10.6 和 iOS 4 开始,也可以使用块进行排序:

    NSArray *sortedArray;
    sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(Person *a, Person *b) {
        return [a.birthDate compare:b.birthDate];
    }];
    

    性能

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

    【讨论】:

    • 第一个示例有一个错误:您将一个对象中的birthDate 实例变量与另一个对象本身进行比较,而不是其birthDate 变量。
    • @Martin:谢谢!有趣的是,在我获得 75 票赞成之前没有其他人注意到。
    • 因为这是公认的答案,因此可能被大多数用户认为是确定的,添加第三个基于块的示例可能会有所帮助,以便用户也知道它的存在。
    • @orange80:我试过了。我没有Mac了,如果你能看一下代码就好了。
    • 如果你有NSMutableArray,我更喜欢使用sortUsingDescriptorssortUsingFunctionsortUsingSelector的方法。只要数组是可变的,我通常不需要排序副本。
    【解决方案2】:

    NSMutableArray方法sortUsingFunction:context:

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

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

    此函数返回NSComparisonResult:如果PersonA.birthDate PersonB.birthDate,则返回NSOrderedAscending。如果PersonA.birthDate > PersonB.birthDate,它将返回NSOrderedDescending。最后,如果PersonA.birthDate == PersonB.birthDate,它将返回NSOrderedSame

    这是粗略的伪代码;您将需要充实一个日期与另一个日期“更少”、“更多”或“相等”的含义(例如比较秒-since-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;
    }
    

    如果您经常这样做,内联可能会加快一点速度。

    【讨论】:

    • 使用 sortUsingFunction:context: 可能是最 c-ish 的方式,而且绝对是最不可读的方式。
    • 这并没有什么问题,但我认为现在有更好的选择。
    • 也许吧,但我认为对于具有 Java 背景的人来说,它的可读性不会降低,他们可能正在寻找类似于 Java 的抽象 Comparator 类的东西,它实现了 compare(Type obj1, Type obj2 )。
    • 我感觉你们中的一些人正在寻找任何理由来批评这个完美的答案,即使这种批评几乎没有技术价值。很奇怪。
    • @Yar:您可以使用我在第一段中提供的解决方案,也可以使用多个排序描述符。 sortedArrayUsingDescriptors: 将排序描述符数组作为参数。
    【解决方案3】:

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

    【讨论】:

    • 你实际上并不需要“(Score *)”演员,你可以做“Score *s1 = obj1;”因为 id 会很高兴地转换为任何东西而不会收到编译器的警告:-)
    • right orange80 downcasting 不需要在弱变量之前进行强制转换。
    • 您应该始终将 nil 与 not-nil 排序到顶部或底部,因此默认的结束返回可能是 return ((!obj1 &amp;&amp; !obj2) ? NSOrderedSame : (obj1 ? NSOrderedAscending : NSOrderedDescending))
    • 嘿,克里斯,我尝试了这段代码,我在我的程序中进行了刷新..我第一次做正确的工作,得到了降序输出..但是当我刷新时。(执行具有相同数据的相同代码)它改变了顺序,它不是降序的。假设我的数组中有 4 个对象,3 个相同的数据,1 个不同。
    • 如果您确实期望不属于“Score”类的对象,则需要更加小心地对它们进行排序。否则,您会遇到 other == score1
    【解决方案4】:

    从 iOS 4 开始,您还可以使用块进行排序。

    对于这个特定示例,我假设您的数组中的对象有一个“位置”方法,该方法返回一个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];
    

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

    【讨论】:

      【解决方案5】:

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

      这就像一个魅力:

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

      【讨论】:

        【解决方案6】:

        Georg Schölly's second answer 中缺少一个步骤,但它可以正常工作。

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

        // 添加 's' 因为我复制和粘贴时浪费了时间,并且在 sortedArrayUsingDescriptors 中没有 's' 失败

        【讨论】:

        • 方法调用其实是“sortedArrayUsingDescriptors:”,末尾有一个's'。
        【解决方案7】:
        NSSortDescriptor *sortDescriptor;
        sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease];
        NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
        NSArray *sortedArray;
        sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];
        

        谢谢,一切正常……

        【讨论】:

          【解决方案8】:

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

          然后你会用@selector(compare:) 调用sortedArrayUsingSelector: 并且应该完成。

          还有其他方法,但据我所知,Comparable 接口没有 Cocoa-equiv。使用sortedArrayUsingSelector: 可能是最轻松的方式。

          【讨论】:

            【解决方案9】:

            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一点说明

            【讨论】:

              【解决方案10】:

              对于NSMutableArray,使用sortUsingSelector 方法。它在原地排序,而不创建新实例。

              【讨论】:

              • 只是一个更新:我也在寻找对可变数组进行排序的东西,现在对于 iOS 7 的所有“sortedArrayUsing”方法都有“sortUsing”等效方法。例如@987654323 @.
              【解决方案11】:

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

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

              【讨论】:

                【解决方案12】:

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

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

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

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

                上面的代码完成了为每个排序键获取一个整数值并比较它们的工作,作为如何做到这一点的说明。由于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]];
                

                我更喜欢简单的语句和大量的临时变量,因为代码更容易阅读,也更容易调试。无论如何,编译器都会优化掉临时变量,因此一体化版本没有任何优势。

                【讨论】:

                  【解决方案13】:

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

                   NSSortDescriptor *sortingDescriptor;
                   sortingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                                         ascending:YES];
                   NSArray *sortArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];
                  

                  【讨论】:

                    【解决方案14】:
                    -(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted 
                    {
                      NSArray *sortedArray;
                      sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 
                      {
                        return [a compare:b];
                     }];
                     return [sortedArray mutableCopy];
                    }
                    

                    【讨论】:

                    • 当返回一个新数组时,为什么要传入一个可变数组。为什么要创建一个包装器?
                    【解决方案15】:

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

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

                    【讨论】:

                    【解决方案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

                    【讨论】:

                      【解决方案17】:

                      我在一些项目中使用了 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];
                      

                      【讨论】:

                        【解决方案18】:

                        排序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];
                        

                        【讨论】:

                          【解决方案19】:

                          使用 NSComparator 排序

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

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

                          使用 NSSortDescriptor 进行排序
                          假设,作为一个例子,我们有一个包含自定义类实例的数组,Employee 具有属性 firstname、lastname 和 age。以下示例说明了如何创建一个 NSSortDescriptor,该 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/

                          【讨论】:

                            【解决方案20】:

                            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)
                            

                            【讨论】:

                              【解决方案21】:

                              就我而言,我使用“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
                              

                              【讨论】:

                                【解决方案22】:

                                您必须创建 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)
                                

                                【讨论】:

                                  【解决方案23】:

                                  在 Swift 中排序数组


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

                                  现在让extensionArray 对应User。简而言之,让我们只为那些只有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)
                                  

                                  extension 中的上述方法只有在 Array 的类型为 [User] || Array&lt;User&gt;

                                  【讨论】:

                                    【解决方案24】:

                                    像这样用于嵌套对象,

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

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

                                    【讨论】:

                                      【解决方案25】:

                                      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
                                          }
                                      

                                      【讨论】:

                                        【解决方案26】:
                                          let sortedUsers = users.sorted {
                                            $0.firstName < $1.firstName
                                         }
                                        

                                        【讨论】:

                                        • 问题是关于 NSMutableArray,而不是关于 Swift 中的数组集合
                                        【解决方案27】:
                                        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(@"===============================");
                                        

                                        【讨论】:

                                          猜你喜欢
                                          • 1970-01-01
                                          • 2013-11-08
                                          • 2012-02-12
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 2012-05-15
                                          相关资源
                                          最近更新 更多