假设我有一个n-by-m的二维数组和一根魔杖按某一列对其进行排序,其余的列以相同的顺序“移动”,因为它们具有“意义”行。
示例:
name number somethingrepeatable
john 543 2
peter 4312 4
jane 234 2
现在,我所拥有的代码会正确排序最后一列,但不会区分john和jane行,因为应用sort的列包含2,结果就是这样:
name number somethingrepeatable
john 543 2
jane 234 2
peter 4312 4
除了要求代码本身之外,我还想知道如何解决这个问题。
到目前为止,这是我的代码:
- (Matrix*) sortByColumn: (NSUInteger) columnNumber{
NSMutableArray * column_in_array = [[NSMutableArray alloc]init];
for(int k=0;k<[self numberOfRows];k++) @autoreleasepool{
[column_in_array addObject: [self objectInRow:k column:columnNumber]];
}
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:nil
ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSMutableArray *origPositions = [[NSMutableArray alloc]initWithCapacity:[orderedColumn count]];
int pos;
NSNumber *posNSI = [[NSNumber alloc]init];
for(int i=0;i<[orderedColumn count];i++){
pos = (int)[column_in_array indexOfObject:[orderedColumn objectAtIndex:i]];
posNSI = [NSNumber numberWithInt:pos];
[origPositions insertObject:posNSI atIndex:i];
}
Matrix * myReturnMatrix = [[Matrix alloc] initWithRows:[self numberOfRows]
columns:[self numberOfColumns]];
NSUInteger index;
for(int i=0;i<[self numberOfRows];i++){
for(int j=0;j<[self numberOfColumns];j++){
index = [[origPositions objectAtIndex: i] integerValue];
[myReturnArray setObject:[self objectInRow:index column:j] inRow:i column:j];
}
}
return myReturnMatrix;
}
快速“解释”将是: 我将要排序的列存储在数组中,使用sortDescriptor对其进行排序,获取原始列的位置,并使用这些原始位置对剩余列进行排序。
答案 0 :(得分:1)
如果我理解正确您正在尝试进行多键排序:您的主键是最后一列,而您的辅助键是第一列(也许您的第三列是中间列)。
您可以通过进一步采用算法的方法来实现这一目标:
NSMutableArray
,其中包含值0
到numberOfRows-1
,即行标记而不是矩阵中的值。sortUsingComparator:
对此数组进行排序(如果需要,则为sortWithOptions:usingComparator:
,例如,稳定排序)。该方法将给出两个指标,并应比较矩阵中的相应行。简要概述伪代码,这是:
NSMutableArray *arrangement = [NSMutableArray new];
// fill arrangement with @0 through @(numberOfRows-1), i.e. NSNumber objects
[arrangement sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
NSUInteger firstIndex = [obj1 unsignedIntegerValue];
NSUInteger secondIndex = [obj2 unsignedIntegerValue];
// compare matrix rows firstIndex & secondIndex
// first compare values in last column,
// if last column values are equal compare values in first column
// ditto for middle column if required
}];
// arrangement now contains the sorted order of the rows - construct result matrix
HTH
答案 1 :(得分:0)
您应该考虑使用自定义NSSortDescriptor
如果您的模型是一个NSDictionary对象数组,也可能更容易。
答案 2 :(得分:0)
这是我最终提出的代码,以保持所有列与已排序的列“同步”,我必须创建一个新类,以便我可以存储“原始位置”和列所具有的任何数据:
NSMutableArray * arrayForOrigPos_unsorted = [[NSMutableArray alloc]init];
for(int k=0;k<[self numberOfRows];k++){
origPosition *oP = [[origPosition alloc]init];
[oP setMyOrigPos:k];
[oP setMyObj:[self objectInRow:k column:columnNumber]];
[arrayForOrigPos_unsorted addObject: oP];
}
NSArray *arrayForOrigPos_sorted = nil;
if(!allNumbers){
arrayForOrigPos_sorted = [arrayForOrigPos_unsorted sortedArrayUsingComparator:^(origPosition *a, origPosition *b) {
return [a.myObj localizedCaseInsensitiveCompare:b.myObj];
}];
}else{
arrayForOrigPos_sorted = [arrayForOrigPos_unsorted sortedArrayUsingComparator:^(origPosition *a, origPosition *b) {
return [a.myObj compare:b.myObj options:NSNumericSearch];
}];
}
Matrix * nuevo = [[Matrix alloc] initWithRows:[self numberOfRows]
columns:[self numberOfColumns]];
NSUInteger indice;
for(int i=0;i<[self numberOfRows];i++){
for(int j=0;j<[self numberOfColumns];j++){
if([[arrayForOrigPos_sorted objectAtIndex: i] respondsToSelector:@selector(myOrigPos)]){
indice = [[arrayForOrigPos_sorted objectAtIndex: i] myOrigPos];
[nuevo setObject:[self objectInRow:indice column:j] inRow:i column:j];
}
}