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

前端 未结 27 3311
予麋鹿
予麋鹿 2020-11-21 04:45

What I want to do seems pretty simple, but I can\'t find any answers on the web. I have an NSMutableArray of objects, and let\'s say they are \'Person\' objects

相关标签:
27条回答
  • 2020-11-21 05:10
    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(@"===============================");
    
    0 讨论(0)
  • 2020-11-21 05:12

    See the NSMutableArray method sortUsingFunction:context:

    You will need to set up a compare function which takes two objects (of type Person, since you are comparing two Person objects) and a context parameter.

    The two objects are just instances of Person. The third object is a string, e.g. @"birthDate".

    This function returns an NSComparisonResult: It returns NSOrderedAscending if PersonA.birthDate < PersonB.birthDate. It will return NSOrderedDescending if PersonA.birthDate > PersonB.birthDate. Finally, it will return NSOrderedSame if PersonA.birthDate == PersonB.birthDate.

    This is rough pseudocode; you will need to flesh out what it means for one date to be "less", "more" or "equal" to another date (such as comparing seconds-since-epoch etc.):

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

    If you want something more compact, you can use ternary operators:

    NSComparisonResult compare(Person *firstPerson, Person *secondPerson, void *context) {
      return ([firstPerson birthDate] < [secondPerson birthDate]) ? NSOrderedAscending : ([firstPerson birthDate] > [secondPerson birthDate]) ? NSOrderedDescending : NSOrderedSame;
    }
    

    Inlining could perhaps speed this up a little, if you do this a lot.

    0 讨论(0)
  • 2020-11-21 05:14

    Your Person objects need to implement a method, say compare: which takes another Person object, and return NSComparisonResult according to the relationship between the 2 objects.

    Then you would call sortedArrayUsingSelector: with @selector(compare:) and it should be done.

    There are other ways, but as far as I know there is no Cocoa-equiv of the Comparable interface. Using sortedArrayUsingSelector: is probably the most painless way to do it.

    0 讨论(0)
  • 2020-11-21 05:14

    I just done multi level sorting based on custom requirement.

    //sort the values

        [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

    0 讨论(0)
  • 2020-11-21 05:15
    NSSortDescriptor *sortDescriptor;
    sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    NSArray *sortedArray;
    sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];
    

    Thanks, it's working fine...

    0 讨论(0)
  • 2020-11-21 05:16

    I've used sortUsingFunction:: in some of my projects:

    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];
    
    0 讨论(0)
提交回复
热议问题