উদ্দেশ্য-সিতে সংস্করণ সংখ্যাগুলির তুলনা করুন


87

আমি একটি অ্যাপ্লিকেশন লিখছি যা আইটেম এবং সংস্করণ নম্বর সহ ডেটা গ্রহণ করে। সংখ্যাগুলি "1.0.0" বা "1.2 .2" এর মতো বিন্যাসিত। এই সংস্করণ সংখ্যাগুলি কীভাবে তুলনা করব? আমি মনে করি তাদের প্রথমে স্ট্রিং হিসাবে ফর্ম্যাট করতে হবে, না? "১.২.১" "1.0.0" এর পরে আসে তা নির্ধারণ করার জন্য আমার কাছে কী বিকল্প রয়েছে?


আমি লিখেছিলাম যে ছোট লাইব্রেরি সহজেই ওবজে-সি-তে 2 সংস্করণ স্ট্রিংয়ের তুলনা করতে পারে। সাধারণত আইওএস এ। গিটহাব পৃষ্ঠায়
নেমব্লেটন

4
এটি ভার্সন স্কিমটি কী তা সুনির্দিষ্টভাবে স্পষ্ট করতে সহায়তা করে। কারও কারও কাছে অতিরিক্ত যুক্তিযুক্ত ফর্ম্যাট থাকতে পারে।
uchuugaka

উত্তর:


244

"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
}

6
আমি এই পদ্ধতিটি ব্যবহার করছিলাম, এবং আমি সম্প্রতি পেয়েছি যে তুলনা করার সময় এটি ভুল ফলাফলগুলি (যা আমি বিবেচনা করি) ফিরে আসে অর্থাত: ২.৪.৪ এর সাথে ২.৪.৪ এর সাথে। আমি বিশ্বাস করি যে ২.৪.০6 হ'ল ২.৪.৪ এর চেয়ে কম হওয়া উচিত তবে আমি ভুল করছি ... কোনও চিন্তাভাবনা?
ওমর

7
@ ওমর: কেন 06 এবং 6 নয়? আমি মনে করি বেশিরভাগ বিকাশকারীরা ২.৪.০6-এর তুলনায় ২.৪.৪ এর চেয়ে বেশি সংস্করণ হিসাবে বিবেচনা করবেন।
স্টিফেন মেলভিন 20

4
এটি দুর্দান্ত এবং সাধারণ তবে খুব সাধারণ সংস্করণ স্কিমের উপর নির্ভর করে।
uchuugaka

11
@ স্কটবারেরোয়েটস আমি অবশ্যই আশা করব যে এটি কীভাবে কাজ করে না, কারণ এর অর্থ হবে "1.2.3" "1.1.12" (123 <1112) এর চেয়ে কম হবে! অ্যাপল সাবধানতার সাথে বলেছে, " স্ট্রিংয়ের মধ্যে সংখ্যাগুলি সংখ্যার মান ব্যবহার করে তুলনা করা হয় "। অর্থাত, স্ট্রিংয়ের মধ্যে সংখ্যার সেটগুলির প্রতিটি তুলনা করা হবে (মূলত, componentsSeparatedByStringপদ্ধতির)। আপনি নিজে সঙ্গে পরীক্ষা করতে পারেন @"1.8"বনাম @"1.7.2.3.55"করিয়া দেখ, 1.8 এগিয়ে আসে আউট।
ডোলিও

4
এনএসনুমারিকস অনুসন্ধান "1.0%" "1.0.0" এর চেয়ে কম বলে মনে করে। আমার উদ্দেশ্যে যথেষ্ট নমনীয় নয়।
ববিকস

17

আমি আমার পদ্ধতিটি যুক্ত করব, যা কোনও সংখ্যক উপাদানগুলির সাথে কঠোরভাবে সংখ্যাসূচক সংস্করণগুলির (কোন, বি, আরসি ইত্যাদি) তুলনা করে।

+ (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;
}

13

1 <1.0 <1.0.0 ইত্যাদির সমস্যা সমাধানের জন্য এটি নাথান ডি ভ্রিজের উত্তরের একটি সম্প্রসারণ is

প্রথমে আমরা একটি সংস্করণ সহ আমাদের সংস্করণ স্ট্রিংয়ে অতিরিক্ত ".0" এর সমস্যার সমাধান করতে পারি NSString:

@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

উপরের NSStringবিভাগের সাথে আমরা অযৌক্তিক .0 গুলি নামাতে আমাদের সংস্করণ নম্বরগুলি সংক্ষিপ্ত করতে পারি

NSString* requiredVersion = @"1.2.0";
NSString* actualVersion = @"1.1.5";

requiredVersion = [requiredVersion shortenedVersionNumberString]; // now 1.2
actualVersion = [actualVersion shortenedVersionNumberString]; // still 1.1.5

এখন আমরা নাথান ডি ভ্রাইসের প্রস্তাবিত সুন্দরভাবে সহজ পদ্ধতিটি ব্যবহার করতে পারি:

if ([requiredVersion compare:actualVersion options:NSNumericSearch] == NSOrderedDescending) {
  // actualVersion is lower than the requiredVersion
}

এটি নাথান ডি ভ্রিজের সমাধানের সাথে মিলিত সেরা এবং সবচেয়ে মার্জিত উত্তর।
ডালমাজিও

এটি কি এখনও বলবে না যে 7.4.2 7.5 এর চেয়ে বেশি সংস্করণ?
ট্রেস

@ ট্রেস নং NSNumericS Search অপশন হিসাবে পাস করা হয়েছে, স্ট্রিংগুলি সংখ্যা হিসাবে তুলনা করা হয়, এইভাবে 7.4.2 <7.5
ডোনালিয়া

9

আমি নিজেই এটি তৈরি করেছি, বিভাগ ব্যবহার করুন ..

উৎস..

@implementation NSString (VersionComparison)
- (NSComparisonResult)compareVersion:(NSString *)version{
    NSArray *version1 = [self componentsSeparatedByString:@"."];
    NSArray *version2 = [version componentsSeparatedByString:@"."];
    for(int i = 0 ; i < version1.count || i < version2.count; i++){
        NSInteger value1 = 0;
        NSInteger value2 = 0;
        if(i < version1.count){
            value1 = [version1[i] integerValue];
        }
        if(i < version2.count){
            value2 = [version2[i] integerValue];
        }
        if(value1  == value2){
            continue;
        }else{
            if(value1 > value2){
                return NSOrderedDescending;
            }else{
                return NSOrderedAscending;
            }
        }
    }
    return NSOrderedSame;
}

পরীক্ষা ..

NSString *version1 = @"3.3.1";
NSString *version2 = @"3.12.1";
NSComparisonResult result = [version1 compareVersion:version2];
switch (result) {
    case NSOrderedAscending:
    case NSOrderedDescending:
    case NSOrderedSame:
         break;
    }

অসাধারণ! এই থ্রেডে NSCompenderResult ব্যবহার করা এটিই একমাত্র উদাহরণ যা 7.28.2 এবং 7.28 সঠিকভাবে তুলনা করে।
কোকপোকস

8

স্পার্কল (ম্যাকোসের জন্য সর্বাধিক জনপ্রিয় সফ্টওয়্যার আপডেট ফ্রেমওয়ার্ক) এর মধ্যে রয়েছে এস এস স্ট্যান্ডার্ডভার্সকমারেটর ক্লাস যা এটি করে এবং এটি বিল্ড নম্বর এবং বিটা মার্কারগুলিকেও গ্রহণ করে। অর্থাৎ এটি সঠিকভাবে তুলনা করে 1.0.5 > 1.0.5b7বা 2.0 (2345) > 2.0 (2100)। কোডটি কেবল ফাউন্ডেশন ব্যবহার করে, সুতরাং আইওএসেও কাজ করা উচিত।


6

আমার এনএসএসস্ট্রিং বিভাগটি দেখুন যা গিথুবটিতে সহজ সংস্করণ চেকিং কার্যকর করে; https://github.com/stijnster/NSString-compareToVersion

এটি একটি এনএস কম্পোরিয়েন্স রেজাল্ট ফিরিয়ে দেবে যা ব্যবহারের পরে আরও নির্ভুল;

সাহায্যকারীদেরও যুক্ত করা হয়;


4

সুইফট ২.২ সংস্করণ:

let currentStoreAppVersion = "1.10.2"
let minimumAppVersionRequired = "1.2.2"
if currentStoreAppVersion.compare(minimumAppVersionRequired, options: NSStringCompareOptions.NumericSearch) ==
            NSComparisonResult.OrderedDescending {
            print("Current Store version is higher")
        } else {
            print("Latest New version is higher")
        }

সুইফট 3 সংস্করণ:

let currentStoreVersion = "1.1.0.2"
let latestMinimumAppVersionRequired = "1.1.1"
if currentStoreVersion.compare(latestMinimumAppVersionRequired, options: NSString.CompareOptions.numeric) == ComparisonResult.orderedDescending {
print("Current version is higher")
} else {
print("Latest version is higher")
}

4

সংস্করণ তুলনার জন্য এখানে সুইফট 4.0 + কোড রয়েছে

 let currentVersion = "1.2.0"

 let oldVersion = "1.1.1"

 if currentVersion.compare(oldVersion, options: NSString.CompareOptions.numeric) == ComparisonResult.orderedDescending {
        print("Higher")
    } else {
        print("Lower")
    }

3

আমি ভেবেছিলাম আমি এই জন্য আমি একসাথে টানা একটি ফাংশন ভাগ করব। এটি মোটেই নিখুঁত নয়। উদাহরণ এবং ফলাফল যে একবার দেখুন। তবে আপনি যদি নিজের সংস্করণ নম্বরগুলি পরীক্ষা করে দেখছেন (যা আমাকে ডাটাবেস স্থানান্তরের মতো জিনিস পরিচালনা করতে হবে) তবে এটি কিছুটা সহায়তা করতে পারে।

(এছাড়াও, পদ্ধতিটিতে লগ স্টেটমেন্টগুলি অবশ্যই মুছে ফেলুন those সেগুলি এখানে যা আছে তা আপনাকে দেখতে সহায়তা করার জন্য রয়েছে)

পরীক্ষা:

[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"];

ফলাফল:

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

খেয়াল করুন যে আলফা কাজ করে তবে আপনাকে এটি সম্পর্কে খুব সতর্কতা অবলম্বন করতে হবে। আপনি একবারে আলফা হয়ে গেলে এর পিছনে অন্য কোনও ছোটখাটো সংখ্যা পরিবর্তন করে আপনি এটি প্রসারিত করতে পারবেন না।

কোড:

- (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;
}

3

আমার আইওএস গ্রন্থাগার AppUpdateTracker একটি রয়েছে NSString বিভাগ তুলনা এই সাজানোর সঞ্চালন। (বাস্তবায়ন ডোনাএলির উত্তর ভিত্তিতে তৈরি )

ব্যবহার নিম্নরূপ হবে:

[@"1.4" isGreaterThanVersionString:@"1.3"]; // YES
[@"1.4" isLessThanOrEqualToVersionString:@"1.3"]; // NO

অতিরিক্তভাবে, আপনি এটি আপনার অ্যাপ্লিকেশনটির ইনস্টলেশন / আপডেটের অবস্থানটি ট্র্যাক রাখতে ব্যবহার করতে পারেন:

[AppUpdateTracker registerForAppUpdatesWithBlock:^(NSString *previousVersion, NSString *currentVersion) {
    NSLog(@"app updated from: %@ to: %@", previousVersion, currentVersion);
}];
[AppUpdateTracker registerForFirstInstallWithBlock:^(NSTimeInterval installTimeSinceEpoch, NSUInteger installCount) {
    NSLog(@"first install detected at: %f amount of times app was (re)installed: %lu", installTimeSinceEpoch, (unsigned long)installCount);
}];
[AppUpdateTracker registerForIncrementedUseCountWithBlock:^(NSUInteger useCount) {
    NSLog(@"incremented use count to: %lu", (unsigned long)useCount);
}];

v4.21 <4.3? যদি ([এই সংস্করণটি গ্রেটারথানঅরকুয়ালটিও ভার্সন স্ট্রিং: @ "4.3"])
জোহানডপপ

না, 4.21 213 হিসাবে 4.3 এর চেয়ে বেশি হিসাবে বিবেচিত হয় 3. আপনার সমতা তুলনা সন্তুষ্ট করার জন্য, আপনি 4.21 সাথে 4.30 এর তুলনা করতে চান। নাথান ডি ভ্রিজের উত্তরের মন্তব্যগুলিতে আলোচনাটি দেখুন ।
স্টাননার

0

গ্লিবিসির একটি ফাংশন রয়েছে strverscmpএবং versionsort... দুর্ভাগ্যক্রমে, আইফোনে পোর্টেবল নয়, তবে আপনি নিজের লিখতে পারেন মোটামুটি সহজে। এটি (স্বাক্ষরিত) পুনঃ-বাস্তবায়ন কেবল ডকুমেন্টযুক্ত আচরণ পড়া থেকে আসে, এবং গ্লিবিকের উত্স কোডটি পড়ে না।

int strverscmp(const char *s1, const char *s2) {
    const char *b1 = s1, *b2 = s2, *e1, *e2;
    long n1, n2;
    size_t z1, z2;
    while (*b1 && *b1 == *b2) b1++, b2++;
    if (!*b1 && !*b2) return 0;
    e1 = b1, e2 = b2;
    while (b1 > s1 && isdigit(b1[-1])) b1--;
    while (b2 > s2 && isdigit(b2[-1])) b2--;
    n1 = strtol(b1, &e1, 10);
    n2 = strtol(b2, &e2, 10);
    if (b1 == e1 || b2 == e2) return strcmp(s1, s2);
    if (n1 < n2) return -1;
    if (n1 > n2) return 1;
    z1 = strspn(b1, "0"), z2 = strspn(b2, "0");
    if (z1 > z2) return -1;
    if (z1 < z2) return 1;
    return 0;
}

4
এটিকে কেবল ভয়ঙ্কর দেখাচ্ছে। অবজেক্টিভ-সি সম্পর্কে আমার যে জিনিসগুলি সবচেয়ে বেশি পছন্দ তা হ'ল বেশিরভাগ অংশের জন্য আমাকে আর সরল সি নিয়ে কাজ করতে হবে না।
লুকাশ পেটর

0

আপনি যদি জানেন যে প্রতিটি সংস্করণ সংখ্যায় বিন্দু দ্বারা পৃথক 3 টি পূর্ণসংখ্যা থাকবে, আপনি সেগুলি পার্স করতে পারেন (উদাহরণস্বরূপ ব্যবহার করে sscanf(3)) এবং তাদের তুলনা করতে পারেন:

const char *version1str = "1.0.1";
const char *version2str = "1.2.5";
int major1, minor1, patch1;
int major2, minor2, patch2;
if(sscanf(version1str, "%d.%d.%d", &major1, &minor1, &patch1) == 3 &&
   sscanf(version2str, "%d.%d.%d", &major2, &minor2, &patch2) == 3)
{
    // Parsing succeeded, now compare the integers
    if(major1 > major2 ||
      (major1 == major2 && (minor1 > minor2 ||
                           (minor1 == minor2 && patch1 > patch2))))
    {
        // version1 > version2
    }
    else if(major1 == major2 && minor1 == minor2 && patch1 == patch2)
    {
        // version1 == version2
    }
    else
    {
        // version1 < version2
    }
}
else
{
    // Handle error, parsing failed
}

0

দ্রুততম সংস্করণটি পরীক্ষা করতে আপনি নিম্নলিখিতটি ব্যবহার করতে পারেন

switch newVersion.compare(currentversion, options: NSStringCompareOptions.NumericSearch) {
    case .OrderedDescending:
        println("NewVersion available  ")
        // Show Alert Here

    case .OrderedAscending:
        println("NewVersion Not available  ")
    default:
        println("default")
    }

আশা করি এটি সহায়ক হতে পারে।


0

এখানে একটি পুনরাবৃত্ত ফাংশন যা কোনও দৈর্ঘ্যের একাধিক সংস্করণ বিন্যাসের সাথে কাজ করে। এটি @ "1.0" এবং @ "1.0.0" এর জন্যও কাজ করে

static inline NSComparisonResult versioncmp(const NSString * a, const NSString * b)
{
    if ([a isEqualToString:@""] && [b isEqualToString:@""]) {
        return NSOrderedSame;
    }

    if ([a isEqualToString:@""]) {
        a = @"0";
    }

    if ([b isEqualToString:@""]) {
        b = @"0";
    }

    NSArray<NSString*> * aComponents = [a componentsSeparatedByString:@"."];
    NSArray<NSString*> * bComponents = [b componentsSeparatedByString:@"."];
    NSComparisonResult r = [aComponents[0] compare:bComponents[0] options:NSNumericSearch];

    if(r != NSOrderedSame) {
        return r;
    } else {
        NSString* newA = (a.length == aComponents[0].length) ? @"" : [a substringFromIndex:aComponents[0].length+1];
        NSString* newB = (b.length == bComponents[0].length) ? @"" : [b substringFromIndex:bComponents[0].length+1];
        return versioncmp(newA, newB);
    }

}

পরীক্ষার নমুনা:

versioncmp(@"11.5", @"8.2.3");
versioncmp(@"1.5", @"8.2.3");
versioncmp(@"1.0", @"1.0.0");
versioncmp(@"11.5.3.4.1.2", @"11.5.3.4.1.2");
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.