9

我有几个需要并排排序的数组。

例如,第一个数组有名称:@[@"Joe", @"Anna", @"Michael", @"Kim"],另一个数组保存地址:@[@"Hollywood bld", @"Some street 3", @"That other street", @"country road"],数组的索引放在一起。“乔”住在“好莱坞大厦”等等。

我想按字母顺序对名称数组进行排序,然后将地址数组排在旁边,以便它们仍然在一起,“Hollywood bld”与“Joe”具有相同的索引。我知道如何按字母顺序对一个数组进行排序

NSSortDescriptor *sort=[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:NO];
[myArray sortUsingDescriptors:[NSArray arrayWithObject:sort]];

但是有什么简单的方法可以使用适当的顺序对第二个数组进行排序?

4

4 回答 4

11
  1. 创建一个排列数组,最初设置为p[i]=i
  2. name根据第一个数组的键对排列进行排序
  3. 使用排列对两个数组重新排序

示例:假设第一个数组是{"quick", "brown", "fox"}. 排列从 开始,在排序之后{0, 1, 2}变为。{1, 2, 0}现在您可以遍历排列数组,并根据需要重新排序原始数组和第二个数组。

NSArray *first = [NSArray arrayWithObjects: @"quick", @"brown", @"fox", @"jumps", nil];
NSArray *second = [NSArray arrayWithObjects: @"jack", @"loves", @"my", @"sphinx", nil];
NSMutableArray *p = [NSMutableArray arrayWithCapacity:first.count];
for (NSUInteger i = 0 ; i != first.count ; i++) {
    [p addObject:[NSNumber numberWithInteger:i]];
}
[p sortWithOptions:0 usingComparator:^NSComparisonResult(id obj1, id obj2) {
    // Modify this to use [first objectAtIndex:[obj1 intValue]].name property
    NSString *lhs = [first objectAtIndex:[obj1 intValue]];
    // Same goes for the next line: use the name
    NSString *rhs = [first objectAtIndex:[obj2 intValue]];
    return [lhs compare:rhs];
}];
NSMutableArray *sortedFirst = [NSMutableArray arrayWithCapacity:first.count];
NSMutableArray *sortedSecond = [NSMutableArray arrayWithCapacity:first.count];
[p enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSUInteger pos = [obj intValue];
    [sortedFirst addObject:[first objectAtIndex:pos]];
    [sortedSecond addObject:[second objectAtIndex:pos]];
}];
NSLog(@"%@", sortedFirst);
NSLog(@"%@", sortedSecond);
于 2012-09-15T11:33:36.383 回答
10

首先,您可能需要重新考虑一种架构,该架构要求您像这样以并行方式对两个数组进行排序。但话虽如此,您可以通过创建一个临时字典数组来保持两个数组的元素成对。

然后对组合数组进行排序,并再次提取两个数组,按要求排序:

原始数据:

NSArray *names     = @[@"Joe", @"Anna", @"Michael"];
NSArray *addresses = @[@"Hollywood bld", @"Some street 3", @"That other street"];

实际排序代码:

NSMutableArray *combined = [NSMutableArray array];

for (NSUInteger i = 0; i < names.count; i++) {
    [combined addObject: @{@"name" : names[i], @"address": addresses[i]}];
}

[combined sortUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]];

names     = [combined valueForKey:@"name"];
addresses = [combined valueForKey:@"address"];

请注意,valueForKey:在数组上使用会提取一个具有相同大小的新数组,其中填充了原始数组中对象的属性。在这种情况下,它会从原始数组创建新数组,并根据需要进行排序。

这种方法只需要几行代码,并且在需要时易于遵循和调试。

于 2012-10-06T13:40:50.863 回答
5

最好的方法是重组你的数据,这样你就只有一个数组。在您的示例中,最有意义的是创建一个具有名称和地址的新类,将它们放在一个数组中并按名称对其进行排序。

于 2012-09-15T11:29:20.047 回答
3

您可以通过在排序前后跟踪对象的索引来做到这一点,但也许拥有一个拥有所有这些属性的对象会更容易

Person : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *addresss;

然后将这些对象存储到一个数组中,您可以按该数组nameaddress键路径排序

于 2012-09-15T11:28:24.450 回答