je suis en train d'écrire une application qui reçoit les données avec les éléments et les numéros de version. Les chiffres sont formatés comme 1.0.1 ou 1.2.5. Comment puis-je comparer ces numéros de version. Je pense qu'ils doivent être formatés comme une chaîne de caractères en premier, non? Si oui, quelle option dois-je avoir pour objectif C comprendre la 1.2.5 est plus récente que la version 1.0.1?
Réponses
Trop de publicités?C'est la façon la plus simple de comparer les versions, en gardant à l'esprit que "1" < "1.0" < "1.0.0":
NSString* requiredVersion = @"1.2.0";
NSString* actualVersion = @"1.1.5";
if ([requiredVersion compare:actualVersion options:NSNumericSearch] == NSOrderedDescending) {
// actualVersion is lower than the requiredVersion
}
Je vais ajouter ma méthode, ce qui se compare strictement numérique versions (pas de a, b, RC etc.) avec un nombre quelconque de composants.
+ (NSComparisonResult)compareVersion:(NSString*)versionOne toVersion:(NSString*)versionTwo {
NSArray* versionOneComp = [versionOne componentsSeparatedByString:@"."];
NSArray* versionTwoComp = [versionTwo componentsSeparatedByString:@"."];
NSInteger pos = 0;
while ([versionOneComp count] > pos || [versionTwoComp count] > pos) {
NSInteger v1 = [versionOneComp count] > pos ? [[versionOneComp objectAtIndex:pos] integerValue] : 0;
NSInteger v2 = [versionTwoComp count] > pos ? [[versionTwoComp objectAtIndex:pos] integerValue] : 0;
if (v1 < v2) {
return NSOrderedAscending;
}
else if (v1 > v2) {
return NSOrderedDescending;
}
pos++;
}
return NSOrderedSame;
}
C'est une extension à Nathan de Vries réponse à résoudre le problème de l'1 < 1.0 < 1.0.0 etc.
Tout d'abord, nous pouvons aborder le problème de l'extra ".0"'s sur notre chaîne de version avec un NSString
catégorie:
@implementation NSString (VersionNumbers)
- (NSString *)shortenedVersionNumberString {
static NSString *const unnecessaryVersionSuffix = @".0";
NSString *shortenedVersionNumber = self;
while ([shortenedVersionNumber hasSuffix:unnecessaryVersionSuffix]) {
shortenedVersionNumber = [shortenedVersionNumber substringToIndex:shortenedVersionNumber.length - unnecessaryVersionSuffix.length];
}
return shortenedVersionNumber;
}
@end
Ci-dessus, NSString
catégorie, nous pouvons réduire nos numéros de version à la chute de l'inutile .0 s
NSString* requiredVersion = @"1.2.0";
NSString* actualVersion = @"1.1.5";
requiredVersion = [requiredVersion shortenedVersionNumberString]; // now 1.2
actualVersion = [actualVersion shortenedVersionNumberString]; // still 1.1.5
Maintenant, nous pouvons toujours utiliser le magnifiquement simple approche proposée par Nathan de Vries:
if ([requiredVersion compare:actualVersion options:NSNumericSearch] == NSOrderedDescending) {
// actualVersion is lower than the requiredVersion
}
Je pensais que je venais de partager une fonction que j'ai rassemblé pour cette. Il n'est pas parfait du tout. Veuillez prendre un coup d'oeil que les exemples et les résultats. Mais si vous êtes de vérifier vos propres numéros de version (que j'ai à faire pour gérer des choses comme les migrations de base de données), puis cela peut aider un peu.
(aussi, supprimer le journal des déclarations dans la méthode, bien sûr. ceux qui sont là pour vous aider à voir ce qu'il fait c'est tout)
Tests:
[self isVersion:@"1.0" higherThan:@"0.1"];
[self isVersion:@"1.0" higherThan:@"0.9.5"];
[self isVersion:@"1.0" higherThan:@"0.9.5.1"];
[self isVersion:@"1.0.1" higherThan:@"1.0"];
[self isVersion:@"1.0.0" higherThan:@"1.0.1"];
[self isVersion:@"1.0.0" higherThan:@"1.0.0"];
// alpha tests
[self isVersion:@"1.0b" higherThan:@"1.0a"];
[self isVersion:@"1.0a" higherThan:@"1.0b"];
[self isVersion:@"1.0a" higherThan:@"1.0a"];
[self isVersion:@"1.0" higherThan:@"1.0RC1"];
[self isVersion:@"1.0.1" higherThan:@"1.0RC1"];
Résultats:
1.0 > 0.1
1.0 > 0.9.5
1.0 > 0.9.5.1
1.0.1 > 1.0
1.0.0 < 1.0.1
1.0.0 == 1.0.0
1.0b > 1.0a
1.0a < 1.0b
1.0a == 1.0a
1.0 < 1.0RC1 <-- FAILURE
1.0.1 < 1.0RC1 <-- FAILURE
notez que alpha travaille, mais vous devez être très prudent avec elle. une fois que vous aller de l'alpha à un certain point, vous ne pouvez pas étendre qu'en changeant tous les autres numéros mineurs derrière elle.
Code:
- (BOOL) isVersion:(NSString *)thisVersionString higherThan:(NSString *)thatVersionString {
// LOWER
if ([thisVersionString compare:thatVersionString options:NSNumericSearch] == NSOrderedAscending) {
NSLog(@"%@ < %@", thisVersionString, thatVersionString);
return NO;
}
// EQUAL
if ([thisVersionString compare:thatVersionString options:NSNumericSearch] == NSOrderedSame) {
NSLog(@"%@ == %@", thisVersionString, thatVersionString);
return NO;
}
NSLog(@"%@ > %@", thisVersionString, thatVersionString);
// HIGHER
return YES;
}