I'm trying to sort an array that can contain different types of structures within itself. Right now I can't seem to get it to recursively sort itself when it has subarrays in the root array.
In the following code below, I have a test array that contains two sub arrays, but the returned root array is moving the items around in the already sorted subarrays for some reason. The subarrays get properly sorted using recursion, but after the recursion the subarrays lose their previous sort. I'd appreciate any help offered.
Output of sorted subarray:
(
A,
b,
C,
c,
Cc,
cc,
CC,
hhh,
x,
z
)
This is the output of the sorted root array (not what I want):
(
(
z,
A,
b,
hhh,
x,
Cc,
C,
cc,
CC,
c
),
(
z,
A,
b,
hhh,
x,
Cc,
C,
cc,
CC,
c
)
)
Code:
- (void)test
{
NSArray *testArr = @[ @[@"z",@"A",@"b",@"hhh",@"x",@"Cc",@"C",@"cc",@"CC",@"c"],
@[@"z",@"A",@"b",@"hhh",@"x",@"Cc",@"C",@"cc",@"CC",@"c"]
];
self.t = [NSMutableArray arrayWithArray:[self sortedArray:testArr]];
NSLog(@"%@",self.t);
}
- (NSArray *)sortedArray:(NSArray *)input
{
NSArray *newArray = [input sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
NSString *nameOne = @"";
NSString *nameTwo = @"";
if ([obj1 isKindOfClass:[NSString class]])
{
nameOne = obj1;
nameTwo = obj2;
}
else if ([obj1 isKindOfClass:[NSArray class]])
{
NSArray *sorted1stArray = [self sortedArray:obj1];
NSArray *sorted2ndArray = [self sortedArray:obj2];
NSLog(@"%@",sorted1stArray);
NSLog(@"%@",sorted2ndArray);
if ([sorted1stArray.firstObject isKindOfClass:[NSDictionary class]])
{
NSDictionary *firstDict = sorted1stArray.firstObject;
NSDictionary *secondDict = sorted2ndArray.firstObject;
if (firstDict[@"Title"])
{
nameOne = firstDict[@"Title"];
nameTwo = secondDict[@"Title"];
}
}
else if ([sorted1stArray.firstObject isKindOfClass:[NSString class]])
{
nameOne = sorted1stArray.firstObject;
nameTwo = sorted2ndArray.firstObject;
}
}
else if ([obj1 isKindOfClass:[NSDictionary class]])
{
if (obj1[@"Title"])
{
nameOne = obj1[@"Title"];
nameTwo = obj2[@"Title"];
}
}
return [nameOne localizedCaseInsensitiveCompare:nameTwo];
}];
return newArray;
}
The comparator is called for every comparison. That means it is invoked multiple times for every element. Every subarray is then sorted multiple times.
Before first sorting, you should backtrack the structure and sort the inner structures first instead of having a recursive comparator. In other words, don't mix comparator with sorting. Keep it separate.
The code could have the following structure:
Also note that the sorting of substructures is not reflected in the result. It's not saved anywhere, it's just temporarily created in the comparator.