简体   繁体   中英

Sort NSArray based on another NSArray using sortDescriptors

I have an NSArray with strings objects that don't follow a pattern, like:

DCAZ X.

When I try to sort a similar array by ascending order, I get:

ACDX Z.

That's not the result I want, I need to achieve the same pattern as the reference array. I'm just not sure how to do this using NScomparisonResult or NSSortDescriptor .

The second array , may not be exactly the same, but I need to have the same order. for example, maybe I have DX A. Based on the reference array I need to get DA X.

UPDATE:

Ok, so here is my code:

- (PFQuery *)queryForTable {
    PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];

     // This is the reference array
     NSArray *labels = [@"Café da Manhã", @"Meio da Manhã", @"Almoço", @"Meio da Tarde", @"Final da Tarde", @"Jantar", @"Pós-Treino"];

    NSSortDescriptor *descriptor = 
    [NSSortDescriptor sortDescriptorWithKey:@"refeicao" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
        NSUInteger index1 = [labels indexOfObject:obj1];
        NSUInteger index2 = [labels indexOfObject:obj2];
        return index1 - index2;
    }];

    [query orderBySortDescriptor:descriptor];
    return query;
}

I have an array of PFObject s, which I need to order by the key refeicao .

You will need to write your own comparison method (which can tie in with a sort descriptor as you can implement it as an NSComparator ).

This method will need to find the 2 strings being compared in your reference array and use the index positions for the comparison. The actual values will not be compared, everything is about the position of the corresponding strings in the reference array.

This is kind-of an answer to your original, more general question. It may not be optimally efficient, but looks O(N)-ish. I suspect it's faster than comparators. This assumes that jumbledArray is a subset of referenceArray ; you could get around that if needed.

NSArray *referenceArray = @[@"S", @"E", @"T", @"Z", @"R", @"U", @"L"];
NSArray *jumbledArray = @[@"R", @"E", @"S", @"T"];

NSMutableOrderedSet *setToOrder = [[NSMutableOrderedSet alloc] initWithArray:jumbledArray];

NSUInteger insertIndex = 0;

for (NSString *refString in referenceArray) {
    NSUInteger presentIndex = [setToOrder indexOfObject:refString]; // one lookup, presumably cheap

    if (presentIndex != NSNotFound) {
        [setToOrder moveObjectsAtIndexes:[NSIndexSet indexSetWithIndex:presentIndex] toIndex:insertIndex];
        insertIndex++;
    }
}
// [setToOrder array] == @[@"S", @"E", @"T", @"R"]

You could generalize this as a method, something like:

- (NSArray *)arrayBySortingArray:(NSArray *)jumbledArray usingReferenceArray:(NSArray *)referenceArray

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM