compare 2 strings (that are numbers)

Go To StackoverFlow.com

0

Possible Duplicate:
How to do a natural sort on an NSArray?
Comparing version numbers

I have my app version saved as an NSString. The version is in the format x.y.z, or x.y (where x,y,z represent integers).

If I want to compare 2 versions (ie: 2 strings representing 2 different/same versions), what is the best way to go about doing this?

Thanks!

Sunny

2012-04-04 00:22
by Wise Shepherd
Give it a try. You'll wanna split the string by the periods, convert to ints, than do your comparisons - Sam Dolan 2012-04-04 00:24
This can be a harder problem than one might think, depending on how you need to compare things. If you just need to compare for exactly equal use isEqualToString:, but if you need to do relative comparisons and partial comparisons then it requires thought and a plan based on how much flexibility you need. (But note that componentsSeparatedByString: can nicely divide a dot-separated version ID. - Hot Licks 2012-04-04 00:33
thanks @Saphrosit. That's exactly what I'm looking for.Should I delete this question - Wise Shepherd 2012-04-04 01:02


0

i had the same problem and couldn't make it work. I finally decided to save version with NSNumber ...saved me a lot of time ...so i suggest you do the same

if you already have the app in the App Store...just do something like:

NSString *string = <get version>
if ([string isKindOfClass:[NSString class]]){
update version and save as NSNumber
}

using NSString to save version may seem like a good idea at first but its tricky when you try to update the app. Using NSNumber is easier because it ...well..uses numbers

so i looked through NSScanner Class Reference and came up with this solution:

int i1,i2,i3;
NSScanner *scanner =[NSScanner alloc]initWithString:string];
BOOL scanI1 = [scanner scanInteger:&i1];
[scanner setScanLocation:3];
BOOL scanI2 = [scanner scanInteger:&i2];
[scanner setScanLocation:5];
BOOL scanI3 = [scanner scanInteger:&i3];
[scanner release];

it's not pretty but it should work

2012-04-04 00:36
by skytz
The if-statement in your code is redundant - if you're saving a variable into an NSString, checking whether it's an NSString will always return a true value.. - Itai Ferber 2012-04-04 00:40
unfortunately that won't work as I'm reading the current version from the app's info.plist, where it is stored as a string - Wise Shepherd 2012-04-04 00:42
do you have more than 1 version released - skytz 2012-04-04 00:43
yes. quite a few versions released - Wise Shepherd 2012-04-04 00:45
this will still work tho...just think about it..if it's an older version it will update to the newest one...with NSNumber...i dont see what could be the problem...you don't care about what version are you updating from...do you - skytz 2012-04-04 00:47
@ItaiFerber the string could be nil..so you have to check for tha - skytz 2012-04-04 00:49
since I'm reading the current version from the app's info.plist, I have no choice but to store the current version as a String. I don't want to need to store the current version somewhere else as a Number too, since there's too high of a chance to introduce a bug by forgetting to update the Number version to match the String version - Wise Shepherd 2012-04-04 00:59


0

There are about a million ways you could go about this, but here is a quick example:

void versionStringComponents(NSString* versionStr_, NSInteger* major__, NSInteger* minor__, NSInteger* bugfix__)
{
    NSArray* elements = [versionStr_ componentsSeparatedByString:@"."];
    *major__ = [[elements objectAtIndex:0] intValue];
    *minor__ = [[elements objectAtIndex:1] intValue];

    *bugfix__ = 0;
    if([elements count] > 2)
    {
        *bugfix__ = [[elements objectAtIndex:2] intValue];
    }
}

bool versionLessThan(NSString* versionStr1_, NSString* versionStr2_)
{
    NSInteger major1 = 0, minor1 = 0, bugfix1 = 0;
    versionStringComponents(versionStr1_, &major1, &minor1, &bugfix1);

    NSInteger major2 = 0, minor2 = 0, bugfix2 = 0;
    versionStringComponents(versionStr2_, &major2, &minor2, &bugfix2);

    return (
        major1 < major2 ||
        (major1 == major2 && minor1 < minor2) ||
        (major1 == major2 && minor1 == minor2 && bugfix1 < bugfix2)
    );
}

Obviously this is a quick little hack, as versionStringComponents() just blindly separates the version numbers from a string, turns them into ints, etc. Also, it could use a few more comparison functions, but I'm sure you can figure those out.

This link, as mentioned by Saphrosit, is a much shorter way of accomplishing the same task, but requires the use of code from the Sparkle framework.

2012-04-04 01:10
by inspector-g