使用NSComparisonResult对NSArray进行递归排序

时间:2015-06-10 20:32:35

标签: ios objective-c arrays recursion comparator

我正在尝试对可以包含不同类型结构的数组进行排序。现在,当它在根数组中有子数组时,我似乎无法以递归方式对其进行自我排序。

在下面的代码中,我有一个包含两个子数组的测试数组,但返回的根数组由于某种原因正在已经排序的子数组中移动项目。使用递归正确地对子数组进行排序,但在递归之后,子数组会丢失其先前的排序。我很感激你提供的帮助。

排序子阵列的输出:

String line = "qwerty/asdfg/xxx/zxcvb";

string[] words = line.Split('/');
int index = Array.IndexOf(words, "xxx");

// Check to make sure you to go beyond the first element
if (index - 1 > -1)
{
    // Previous word
    Console.WriteLine(words[index - 1]);
}

// Check to make sure you to go beyond the last element    
if (index != -1 && index + 1 < words.Length)
{
    // Next word
    Console.WriteLine(words[index + 1]);
}

Console.ReadLine();

这是排序根数组的输出(不是我想要的):

(
    A,
    b,
    C,
    c,
    Cc,
    cc,
    CC,
    hhh,
    x,
    z
)

代码:

 (
        (
        z,
        A,
        b,
        hhh,
        x,
        Cc,
        C,
        cc,
        CC,
        c
    ),
        (
        z,
        A,
        b,
        hhh,
        x,
        Cc,
        C,
        cc,
        CC,
        c
    )
)

2 个答案:

答案 0 :(得分:1)

每次比较都会调用比较器。这意味着它会为每个元素多次调用。然后对每个子阵列进行多次排序。

在第一次排序之前,您应该首先回溯结构并对内部结构进行排序,而不是使用递归比较器。换句话说,不要将比较器与排序混合。保持分开。

代码可以具有以下结构:

- (NSArray *)sortedArray:(NSArray *)input {
   //1. sort every subelement in input recursively

   //2. sort input
}

另请注意,子结构的排序不会反映在结果中。它不会保存在任何地方,只是暂时在比较器中创建。

答案 1 :(得分:0)

如果它只是数组中数组中的字符串,为什么会出现递归解决方案的麻烦?

NSArray *testArr = @[[@[@"z",@"A",@"b",@"hhh",@"x",@"Cc",@"C",@"cc",@"CC",@"c"] mutableCopy],
                     [@[@"z",@"A",@"b",@"hhh",@"x",@"Cc",@"C",@"cc",@"CC",@"c"] mutableCopy
                    ];        
[testArr enumerateObjectsUsingBlock:^(NSMutableArray *subarray, NSUInteger idx, BOOL *stop) {
   [subarray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 localizedCaseInsensitiveCompare:obj2];
   }];
}];
  

...需要使用特定序列(不仅仅是A-Z)进行分类

我在这里展示了一个合理的解决方案:Sort NSmutablearray with two special keys,或者你自己的需要返回NSComparisonResult的比较方法

enum {
   NSOrderedAscending = -1,
   NSOrderedSame,
   NSOrderedDescending 
};
typedef NSInteger NSComparisonResult;

您可以在类别

中定义该方法
@implementation NSString (MySorting)
-(NSComparisonResult)localizedCaseInsensitiveCompareLongestFirst:(NSString *)string
{
    if ([self length] > [string length]) {
        return NSOrderedAscending;
    } else if ([self length] < [string length]) {
        return NSOrderedDescending;
    } else {
        return [self localizedCaseInsensitiveCompare:string];
    }
}
@end

现在改变第一个代码

NSArray *testArr = @[ [@[@"z",@"A",@"b",@"hhh",@"x",@"Cc",@"C",@"cc",@"CC",@"c"] mutableCopy],
                      [@[@"z",@"A",@"b",@"hhh",@"x",@"Cc",@"C",@"cc",@"CC",@"c"] mutableCopy]
                      ];


[testArr enumerateObjectsUsingBlock:^(NSMutableArray *subarray, NSUInteger idx, BOOL *stop) {
   [subarray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
       return [obj1 localizedCaseInsensitiveCompareLongestFirst:obj2];
   }];
}];

我们有

的自定义排序
(
        (
        hhh,
        Cc,
        cc,
        CC,
        A,
        b,
        C,
        c,
        x,
        z
    ),
        (
        hhh,
        Cc,
        cc,
        CC,
        A,
        b,
        C,
        c,
        x,
        z
    )
)