Сначала сортировка двух NSMutableArray по «ближайшему расстоянию»

У меня есть два массива, оба заполнены объектами NSString, например:

NSMutableArray *titles = [[NSMutableArray alloc] initWithObjects:@"Title1", @"Title2", @"Title3", @"Title4", @"Title5", nil];

NSMutableArray *distances = [[NSMutableArray alloc] initWithObjects:@"139.45", @"23.78", @"347.82", @"10.29", @"8.29", nil];

Как я могу сначала отсортировать оба массива по ближайшему расстоянию?

Таким образом, результаты будут такими:

titles = @"Title5", @"Title4", @"Title2", @"Title1", @"Title3"
distances = @"8.29", @"10.29", @"23.78", @"139.45", @"347.82"

Я понимаю, что NSSortDescriptor можно использовать в этих обстоятельствах, но после просмотра документации я все еще не уверен, как это сделать.


person James Anderson    schedule 02.10.2012    source источник


Ответы (4)


Я бы рассортировал расстояния так...

NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];

NSArray *sortedDistances = [listItem sortedArrayUsingComparator: ^(id a, id b) {
    NSNumber *aNum = [f numberFromString:a];
    NSNumber *bNum = [f numberFromString:b];
    return [aNum compare:bNum];
}];

Я не могу придумать особенно быстрый способ отсортировать связанные заголовки, но это должно сработать...

NSMutableArray *sortedTitles = [NSMutableArray array];
NSDictionary *distanceTitle = [NSDictionary dictionaryWithObjects:titles forKeys:distances];

for (NSString *distance in sortedDistances) {
    NSString *associatedTitle = [distanceTitle valueForKey:distance];
    [sortedTitles addObject:associatedTitle];
}
person danh    schedule 02.10.2012

Вы можете использовать блок NSComparator и использовать метод sortedArrayUsingComparator NSArray. В этом блоке вы получите два объекта для сравнения, и на основе результата сравнения вы можете использовать метод NSMutableArray exchangeObjectAtIndex:withObjectAtIndex: для изменения значений заголовков.

person J2theC    schedule 02.10.2012

Вот пример того, как я сортирую массив словарей по значению расстояния:

    -(void)reorderByDistance {
    NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:@"distance" ascending:YES];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
    self.contentArray = [self.contentArray sortedArrayUsingDescriptors:sortDescriptors];
}

И мой словарь выглядит так:

    NSDictionary *dict1 = [[NSDictionary alloc] initWithObjectsAndKeys:@"1", @"id", @"Business #1", @"name", @"This business does some pretty remarkable things", @"description", @"Alley Bar", @"category", @"1.2", @"distance", nil];
person Brayden    schedule 02.10.2012
comment
Спасибо! Можете ли вы привести небольшой пример того, как выглядит ваш NSMutableDictionary с помощью NSLogging? - person James Anderson; 02.10.2012

Одним из подходов было бы создание словаря, отображающего заголовки на расстояния, сортировку расстояний, а затем повторение расстояний для воссоздания заголовков:

NSMutableArray *titles = [[NSMutableArray alloc] initWithObjects:@"Title1", @"Title2", @"Title3", @"Title4", @"Title5", nil];

NSMutableArray *distances = [[NSMutableArray alloc] initWithObjects:@"139.45", @"23.78", @"347.82", @"10.29", @"8.29", nil];

//Create a map of current titles to distances
NSDictionary *titleDistanceMap = [NSDictionary dictionaryWithObjects:titles forKeys:distances];

//Need to sort the strings as numerical values
[distances sortUsingComparator:^(NSString *obj1, NSString *obj2) {

    return [obj1 compare:obj2 options:NSNumericSearch];
}];

//Now re-populate the titles array
[titles removeAllObjects];

for (NSString *distance in distances){
    [titles addObject:[titleDistanceMap objectForKey:distance]];
}
person ChrisH    schedule 02.10.2012