Newbie: compare version string

  • Hi,

    Is there APIs which compare two version strings: like 10.5 is less
    than 10.5.1 or 10.5 is greater than 10.4.11.
    Is it OK to use NSString's compare method? Or should I split those
    strings by period and make scalers from them?

    Norio Ota
  • On 9 Dec 2007, at 8:43 AM, norio wrote:

    > Is there APIs which compare two version strings: like 10.5 is less
    > than 10.5.1 or 10.5 is greater than 10.4.11.
    > Is it OK to use NSString's compare method? Or should I split those
    > strings by period and make scalers from them?

    To my knowledge, there is no such API. My practice is to split by '.'
    and compare components. If you're parsing general version strings, be
    aware that some application version numbers have _four_ components,
    even for released products. (The theory being apparently that you need
    to enumerate bug-fix versions of a bug-fix version.) Also, many
    version strings involve build numbers (some of which are not numeric
    -- e.g. 9B18).

    Finally, if you find what we used to call an Apple-style version --
    1.2b9 -- you have to sort by (v/r/null) > b > a > d.

    A lexical comparison (-[NSString compare:]) won't work, even without
    fourth versions and stage letters. Consider that 10.4.1 < 10.4.11 <
    10.4.2.

    See also the thread(s) from a month or two ago about obtaining and
    comparing system version numbers. It was quasi-religious, and I'm sure
    I haven't assimilated all of it.

    — F
  • On Dec 9, 2007 7:10 AM, Fritz Anderson <fritza...> wrote:
    > On 9 Dec 2007, at 8:43 AM, norio wrote:
    >
    >> Is there APIs which compare two version strings: like 10.5 is less
    >> than 10.5.1 or 10.5 is greater than 10.4.11.
    >> Is it OK to use NSString's compare method? Or should I split those
    >> strings by period and make scalers from them?
    >
    > To my knowledge, there is no such API. My practice is to split by '.'
    > and compare components. If you're parsing general version strings, be
    > aware that some application version numbers have _four_ components,
    > even for released products. (The theory being apparently that you need
    > to enumerate bug-fix versions of a bug-fix version.) Also, many
    > version strings involve build numbers (some of which are not numeric
    > -- e.g. 9B18).
    >
    > Finally, if you find what we used to call an Apple-style version --
    > 1.2b9 -- you have to sort by (v/r/null) > b > a > d.
    >
    > A lexical comparison (-[NSString compare:]) won't work, even without
    > fourth versions and stage letters. Consider that 10.4.1 < 10.4.11 <
    > 10.4.2.

    No, but
    [string1 compare: string2 options: NSNumericSearch]
    should work.

    --
    Clark S. Cox III
    <clarkcox3...>
  • On Dec 9, 2007, at 10:27 AM, Clark Cox wrote:

    > On Dec 9, 2007 7:10 AM, Fritz Anderson <fritza...>
    > wrote:
    >> A lexical comparison (-[NSString compare:]) won't work, even without
    >> fourth versions and stage letters. Consider that 10.4.1 < 10.4.11 <
    >> 10.4.2.
    >
    > No, but
    > [string1 compare: string2 options: NSNumericSearch]
    > should work.

    At least as of 10.4.3, that didn't work correctly with string
    literals, so we use an NSString category method:

    - (NSComparisonResult)numericCompare:(NSString *)otherString{
        return CFStringCompare((CFStringRef)self,
    (CFStringRef)otherString, kCFCompareNumerically);
    }

    --
    adam
  • On Dec 9, 2007 10:39 AM, Adam R. Maxwell <amaxwell...> wrote:
    >
    > On Dec 9, 2007, at 10:27 AM, Clark Cox wrote:
    >
    >> On Dec 9, 2007 7:10 AM, Fritz Anderson <fritza...>
    >> wrote:
    >>> A lexical comparison (-[NSString compare:]) won't work, even without
    >>> fourth versions and stage letters. Consider that 10.4.1 < 10.4.11 <
    >>> 10.4.2.
    >>
    >> No, but
    >> [string1 compare: string2 options: NSNumericSearch]
    >> should work.
    >
    > At least as of 10.4.3, that didn't work correctly with string
    > literals, so we use an NSString category method:
    >
    > - (NSComparisonResult)numericCompare:(NSString *)otherString{
    > return CFStringCompare((CFStringRef)self,
    > (CFStringRef)otherString, kCFCompareNumerically);
    > }

    I can't speak to 10.4.3, but I just tried it out on 10.5.1, and it
    works as expected:

    //begin main.m
    #import <Cocoa/Cocoa.h>

    static NSInteger CompareFunc(id a, id b, void *ignored) {
        return [a compare: b options: NSNumericSearch];
    }

    int main(int argc, char *argv[])
    {
        NSAutoreleasePool  *localPool  = [[NSAutoreleasePool alloc] init];
        NSString *strings[] = {
            @"1",
            @"1.2",
            @"1.5",
            @"1.41",
            @"1.11",
            @"10.2.1",
            @"10.5.11",
            @"10.4.3"
        };

        NSArray *stringArray    = [NSArray arrayWithObjects: strings
                                                      count: sizeof
    strings / sizeof *strings];

        NSArray *sortedArray    = [stringArray sortedArrayUsingFunction:
    CompareFunc context: NULL];

        NSLog(@"Before:\n%@", stringArray);
        NSLog(@"After:\n%@", sortedArray);
        [localPool release];
        return 0;
    }

    //end main.m

    outputs:
    2007-12-09 12:35:21.741 CompareTest[4097:817] Before:
    (
        1,
        "1.2",
        "1.5",
        "1.41",
        "1.11",
        "10.2.1",
        "10.5.11",
        "10.4.3"
    )
    2007-12-09 12:35:21.763 CompareTest[4097:817] After:
    (
        1,
        "1.2",
        "1.5",
        "1.11",
        "1.41",
        "10.2.1",
        "10.4.3",
        "10.5.11"
    )

    --
    Clark S. Cox III
    <clarkcox3...>
  • On Dec 9, 2007, at 12:36 PM, Clark Cox wrote:

    > On Dec 9, 2007 10:39 AM, Adam R. Maxwell <amaxwell...> wrote:
    >>
    >> On Dec 9, 2007, at 10:27 AM, Clark Cox wrote:
    >>
    >>> On Dec 9, 2007 7:10 AM, Fritz Anderson <fritza...>
    >>> wrote:
    >>>> A lexical comparison (-[NSString compare:]) won't work, even
    >>>> without
    >>>> fourth versions and stage letters. Consider that 10.4.1 < 10.4.11 <
    >>>> 10.4.2.
    >>>
    >>> No, but
    >>> [string1 compare: string2 options: NSNumericSearch]
    >>> should work.
    >>
    >> At least as of 10.4.3, that didn't work correctly with string
    >> literals, so we use an NSString category method:
    >>
    >> - (NSComparisonResult)numericCompare:(NSString *)otherString{
    >> return CFStringCompare((CFStringRef)self,
    >> (CFStringRef)otherString, kCFCompareNumerically);
    >> }
    >
    > I can't speak to 10.4.3, but I just tried it out on 10.5.1, and it
    > works as expected:

    Cool, looks like it's fixed.  The problem I'm thinking of was
    described here

    http://www.cocoabuilder.com/archive/message/cocoa/2005/12/4/151822

    and ISTR verifying that it was a problem for us at the time.

    thanks,
    adam
previous month december 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Go to today