3

I have an array which contains strings like frame_10@3x.png , frame_5@3x.png,frame_19@3x.png etc. So I want to sort this array according to the number after the underscore i.e. the correct sequence will be frame_5@3x.png,frame_10@3x.png,frame_19@3x.png.

I tried to use the following method but no result:

NSInteger firstNumSort(id str1, id str2, void *context) {
    int num1 = [str1 integerValue];
    int num2 = [str2 integerValue];

    if (num1 < num2)
        return NSOrderedAscending;
    else if (num1 > num2)
        return NSOrderedDescending;

    return NSOrderedSame;
}

Please suggest how to do this sorting for array.

MByD
  • 135,866
  • 28
  • 264
  • 277
iPhoneDev
  • 1,547
  • 2
  • 13
  • 36
  • For correct answer for alphanumeric array sort see Ben G answere here http://stackoverflow.com/questions/1351182/how-to-sort-a-nsarray-alphabetically – Sam B Feb 28 '17 at 02:46

4 Answers4

8
NSArray *sry_img = [[NSArray alloc]    initWithObjects:@"frame_18@3x.png",@"frame_17@3x.png",@"frame_1222@3x.png",@"frame_10@3x.png",@"frame_3@3x.png",@"frame_4@3x.png",@"frame_4@3x.png",@"frame_1@3x.png",@"frame_4@3x.png",@"frame_4@3x.png",nil];
  NSArray *sortedStrings  = [sry_img sortedArrayUsingSelector:@selector(localizedStandardCompare:)];

NSLog(@"%@",sortedStrings);

Enjy .......

But localizedStandardCompare:, added in 10.6, should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact behavior of this method may be tweaked in future releases, and will be different under different localizations, so clients should not depend on the exact sorting order of the strings.

Nag_iphone
  • 967
  • 7
  • 22
0

you want to do something like:

NSArray *components1 = [str1 componentsSeparatedByString:@"_"];
NSArray *components2 = [str2 componentsSeparatedByString:@"_"];

NSString *number1String = [components1 objectAtIndex:([components1 count] - 1])];
NSString *number2String = [components2 objectAtIndex:([components2 count] - 1])];

return [number1String compare:number2String];
Mike K
  • 2,227
  • 1
  • 12
  • 6
0

You can try this-

NSString *str1 = [[[[str1 componentsSeparatedByString:@"frame_"] objectAtIndex:1]       componentsSeparatedByString:@"@3x.png"] objectAtIndex:0];
int num1 = [str1 integerValue];
rishi
  • 11,779
  • 4
  • 40
  • 59
0

I am not sure if my solution is the best possible approach but it can solve your problem for the time being :) .

1) First I have written a function to get the numbers before @ character in your string and then I implemented simple SELECTION SORT algo to sort the array using this functions.

- (NSString*)getSubStringForString:(NSString*)value {
// First we will cut the frame_ string
NSMutableString *trimmedString = [NSMutableString stringWithString:[value substringWithRange:NSMakeRange(6, [value length]-6)]];

// New String to contain the numbers
NSMutableString *newString = [[NSMutableString alloc] init];

for (int i = 0; i < [trimmedString length] ; i++) {        
    NSString *singleChar = [trimmedString substringWithRange:NSMakeRange(i, 1)];
    if (![singleChar isEqualToString:@"@"]) {
        [newString appendString:singleChar];
    } else {
        break;
    }
}    
return newString;
}

This is the selection Implementation of the algo for sorting. The main logic is in the for loop. You can copy the code in viewDidLoad method to test.

NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"frame_10@3x.png",@"frame_5@3x.png",
                         @"frame_3@3x.png", @"frame_19@3x.png",
                         nil];    
NSLog(@"Values before Sort: %@", array);

int iPos;
int iMin;

for (iPos = 0; iPos < [array count]; iPos++)
{

    iMin = iPos;

    for (int i = iPos+1; i < [array count]; i++)
    {            

        if ([[self getSubStringForString:[array objectAtIndex:i]] intValue] > 
            [[self getSubStringForString:[array objectAtIndex:iMin]] intValue]) {
            iMin = i;
        }

    }

    if ( iMin != iPos )
    {
        NSString *tempValue = [array objectAtIndex:iPos];
        [array replaceObjectAtIndex:iPos withObject:[array objectAtIndex:iMin]];
        [array replaceObjectAtIndex:iMin withObject:tempValue];

    }
}

NSLog(@"Sorted Values: %@", array);

I hope that it can atleast keep you going. :)

Arslan
  • 919
  • 7
  • 16