How i can compare something like "1.0.0a3" n "1.0.0b4" n "1.0.0b11"

Discussion in 'Mac Programming' started by i.yalovecky, Apr 20, 2010.

  1. i.yalovecky macrumors member

    Joined:
    Feb 24, 2010
    #1
    subj

    resulted order must be
    1.0.0a3
    1.0.0b4
    1.0.0b11

    NSString compare:str options:NSNumericSearch

    gives another order
    1.0.0a3
    1.0.0b11
    1.0.0b4
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    You'll have to define your own custom comparator that understands the different components of the numbers (version numbers?).
     
  3. i.yalovecky thread starter macrumors member

    Joined:
    Feb 24, 2010
    #3
    It looks right. But i thought that so usual task already implemented in one of the base frameworks.
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    A usual task is to compare two strings alphabetically or numerically. It is not usual to compare them using an arbitrary combination of the two.
     
  5. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #5
    Sparkle has (BSD-licensed, so usable in non-OSS apps) code for comparing version numbers.
     
  6. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #6
    Learn how to use NSScanner to scanUpToCharactersInSet:[NSCharacterSet decimalDigitCharacterSet], followed by -scanInt:
     
  7. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #7
    This is supposed to work, for example creating three folders with these names in the Finder will sort them correctly. I'd check my code carefully. What happens if you sort "1", "5" and "23" with the same code?
     
  8. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    Post your code, and identify your OS version.

    The following works wherever I try it:
    Code:
    #import <Foundation/Foundation.h>
    
    NSComparisonResult versionCompare( id str1, id str2, void *context )
    {
    	return [str1 compare:str2 options:NSNumericSearch];
    }
    
    int main (int argc, const char * argv[]) 
    {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    	
    	NSArray *unsorted = [NSArray arrayWithObjects: 
    		@"1.0.0b11", @"1.0.0b4", @"1.0.0a3", nil ];
    
    	NSArray* sorted = [unsorted sortedArrayUsingFunction:versionCompare context:nil];
    
    	NSLog( @"unsorted: %@", unsorted );
    	NSLog( @"sorted: %@", sorted );
    
        [pool drain];
        return 0;
    }
    
    Example output:
    Code:
    2010-04-21 09:51:26.600 a.out[4724] unsorted: ("1.0.0b11", "1.0.0b4", "1.0.0a3")
    2010-04-21 09:51:26.600 a.out[4724] sorted: ("1.0.0a3", "1.0.0b4", "1.0.0b11")
    
     
  9. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #9
    Why is this still an issue? There's freely available code that's been tested in hundreds of Mac applications already.
     
  10. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #10
    iTunes sorts

    Brandenburg Concerto No. 2 in F major, BWV 1047 - 2. Andante

    exactly in the right place where I would expect it. Any combination of text and numbers.
     
  11. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #11
    i.yalovecky,

    When I have trouble, I hack some code together. Here is that hack with chown33's array sort added in. Hopefully it will be helpful.


    Code:
    #import <Foundation/Foundation.h>
    
    NSComparisonResult versionCompare( id str1, id str2, void *context )
    {
    	return [str1 compare:str2 options:NSNumericSearch];
    }
    
    
    int main (int argc, const char * argv[]) {
        CFShow(CFSTR("Comparing strings with numbers in them.\n"));
    	
    	NSObject* pool = [[NSAutoreleasePool alloc] init];
    	
    	static NSStringCompareOptions comparisonOptions =  NSNumericSearch;	
    	
    	NSString* lowStr; 
    	lowStr = [NSString stringWithString:@"1.0.0a3"];
    	NSString* midStr;
    	midStr = [NSString stringWithString:@"1.0.0b4"];
    	NSString* highStr;
    	highStr = [NSString stringWithString:@"1.0.0b11"];
    
    	NSInteger ordering;
    	
    	ordering = [lowStr compare: midStr options:comparisonOptions];
    	NSLog(@"ordering of compare return value: %d", ordering);
    	if ( ordering == NSOrderedAscending)
    	{
    		NSLog(@"Expected NSOrderedAscending: %@ < %@", lowStr, midStr);
    	}
    	else if ( ordering == NSOrderedDescending)
    	{
    		NSLog(@"NSOrderedDescending: %@ > %@", lowStr, midStr);
    	}
    	else
    	{
    		NSLog(@"NSOrderedSame: %@ = %@", lowStr, midStr);
    	}
    	
    	
    	ordering = [highStr compare: midStr options: NSNumericSearch];
    	NSLog(@"ordering of compare return value: %d", ordering);
    	if ( ordering == NSOrderedAscending)
    	{
    		NSLog(@"NSOrderedAscending: %@ < %@", highStr, midStr);
    	}
    	else if ( ordering == NSOrderedDescending)
    	{
    		NSLog(@"Expected NSOrderedDescending: %@ > %@", highStr, midStr);
    	}
    	else
    	{
    		NSLog(@"NSOrderedSame: %@ = %@", highStr, midStr);
    	}
    
    
    	NSArray *unsorted = [NSArray arrayWithObjects: midStr, highStr, lowStr, nil ];
    	NSArray* sorted = [unsorted sortedArrayUsingFunction:versionCompare context:nil];
    	NSLog( @"unsorted: %@", unsorted );
    	NSLog( @"sorted: %@", sorted );
    
    
    	[pool release];
    	return 0;
    }
    
     
  12. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #12
    Because why use third party code when it isn't needed. It is nice to know about though.
     
  13. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #13
    Code:
    	static NSStringCompareOptions comparisonOptions =  NSNumericSearch;	
    
    Your code has the potential problem that you store the ordering in a static variable, which is an initialisation that is only performed once when the program starts. If that static variable is changed later, the initialisation will not be done again. Big red flag going up. That's the kind of code where you may _think_ you are using NSNumericSearch, but you aren't. Example:

    Code:
    void test (void) {
      static int i = 5; 
      printf ("i should be five, it is %d\n", i);
      i = 6;
      printf ("i should be six, it is %d\n", i);
    }
    
    When you call test () the first time, it will print 5 and 6. On the second call, it will print 6 and 6.
     
  14. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #14
    I'm confused. That is the options flag, not the ordering result variable. I agree that if I want to change it later, it shouldn't be static.

    Oh, static still allows the variable to be altered.

    EDIT: Did some more research. Static limits scope within declared file so does allow changes. I should have used const.
     

Share This Page