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.