Search code examples
iosobjective-cnsarraynssortdescriptor

Use Two NSSortDescriptor to filter array


I would like to sort an array using the dictionary values "Name" and "Count". It would be Name alphabetically and split the names up into two groupd based on count.

bigger than 0

Smaller than Equal 0

My current implementation looks like this however it dose not split the groups up correctly.

NSSortDescriptor *sortCountDescriptor = [[NSSortDescriptor alloc] initWithKey:@"count" ascending:NO];
NSSortDescriptor *sortNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

NSArray * sortDescriptors = [NSArray arrayWithObjects:sortCountDescriptor, sortNameDescriptor, nil];

NSArray *sortedArray = [myArrayToSort sortedArrayUsingDescriptors:sortDescriptors];

return [sortedArray mutableCopy];

Solution

  • If by grouping you mean making them separate arrays then you need an NSPredicate instead of NSSortDescriptor for count key.

    Try this (from what I understood the array is filled with instances of NSDictionary so I used casting to it. If that assumption is incorrect, the NSPredicate isn't hard to change to some other type or to be made more generic with KVC):

    NSSortDescriptor *sortNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO]; NSArray * sortDescriptors = [NSArray arrayWithObjects:sortNameDescriptor, nil];

    NSArray *sortedArray = [myArrayToSort sortedArrayUsingDescriptors:@[sortNameDescriptor]];
    
    NSPredicate *zeroOrLessPredicate = [NSPredicate predicateWithBlock:^BOOL(id  _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
        if ([[((NSDictionary*)evaluatedObject) objectForKey:@"count"] integerValue] <= 0) {
            return YES;
        }
        else {
            return NO;
        }
    }];
    NSArray *zeroOrLessArray = [sortedArray filteredArrayUsingPredicate:zeroOrLessPredicate];
    
    NSPredicate *moreThanZeroPredicate = [NSCompoundPredicate notPredicateWithSubpredicate:zeroOrLessPredicate];
    NSArray *moreThanZeroArray = [sortedArray filteredArrayUsingPredicate:moreThanZeroPredicate];