I'm trying to sort my arrays with a particular sequence using an NSComparisonResult. I'm unable to figure out how to achieve the sequence I'm wanting.
I'm trying to weight Emojis towards the top (sequence of Emojis doesn't matter), followed by A-Z letters with giving a weight towards lowercase before uppercase, followed by numbers, followed by punctuation, then by symbols, and whatever else after that I dont care about at this point. I've gotten pretty close so far, but am still coming up short with what I want.
The sequence I'm trying to achieve would look like this as the output:
("\Ud83d\Ude03",
a,
A,
aa,
aA,
ab,
aB,
a1,
A1,
1,
01,
11,
001,
0001,
1001,
"#",
"#a",
"#1",
"$12",
"$0012")
Based upon this array as the input:
@[ @"a", @"aA", @"aa", @"A", @"aB", @"11", @"1001", @"ab", @"001", @"01",
@"a1", @"A1", @"", @"0001", @"1", @"#", @"$12", @"$0012", @"#a", @"#1" ];
But this is the output I'm getting:
("\Ud83d\Ude03",
a,
A,
aA,
aa,
aB,
ab,
a1,
A1,
0001,
001,
01,
1,
1001,
11,
"#a",
"#1",
"$0012",
"$12",
"#")
Code:
- (NSArray *)sortedArray:(NSArray *)input
{
NSArray *newArray = [input sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
NSString *nameOne = obj1;
NSString *nameTwo = obj2;
NSString *startOne;
NSString *startTwo;
NSInteger currentIndex = 0;
NSInteger maxIndex = (nameOne.length < nameTwo.length) ? nameOne.length : nameTwo.length;
NSCharacterSet *decimalDigitCharSet = [NSCharacterSet decimalDigitCharacterSet];
NSCharacterSet *punctuationCharSet = [NSCharacterSet punctuationCharacterSet];
NSCharacterSet *symbolCharSet = [NSCharacterSet symbolCharacterSet];
NSMutableCharacterSet *nonPriorityCharSet = [[NSMutableCharacterSet alloc]init];
[nonPriorityCharSet formUnionWithCharacterSet:punctuationCharSet];
[nonPriorityCharSet formUnionWithCharacterSet:symbolCharSet];
do
{
if (currentIndex < maxIndex)
{
startOne = [nameOne substringWithRange:NSMakeRange(currentIndex, 1)];
startTwo = [nameTwo substringWithRange:NSMakeRange(currentIndex, 1)];
currentIndex++;
}
else
{
if (nameOne.length == nameTwo.length)
{
return NSOrderedSame;
}
else
{
return (nameOne.length < nameTwo.length) ? NSOrderedAscending : NSOrderedDescending;
}
}
}
while ([startOne isEqualToString:startTwo]);
{
NSRange rangeOne = [startOne rangeOfCharacterFromSet:nonPriorityCharSet];
NSRange rangeTwo = [startTwo rangeOfCharacterFromSet:nonPriorityCharSet];
if (rangeOne.length > 0 || rangeTwo.length > 0)
{
return (rangeOne.length > 0) ? NSOrderedDescending : NSOrderedAscending;
}
NSRange decimalRangeOne = [startOne rangeOfCharacterFromSet:decimalDigitCharSet];
NSRange decimalRangeTwo = [startTwo rangeOfCharacterFromSet:decimalDigitCharSet];
if (decimalRangeOne.length > 0 || decimalRangeTwo.length > 0)
{
if (decimalRangeOne.length == decimalRangeTwo.length)
{
return (startOne.intValue > startTwo.intValue) ? NSOrderedDescending : NSOrderedAscending;
}
else if (decimalRangeOne.length > decimalRangeTwo.length)
{
return NSOrderedDescending;
}
else if (decimalRangeTwo.length > decimalRangeOne.length)
{
return NSOrderedAscending;
}
}
}
return [nameOne localizedCaseInsensitiveCompare:nameTwo];
}];
return newArray;
}
You started well. But you didn't properly check for all the rules that you have set. I have created some categories based on you rules, and sort using them.