如何对比两个版本号大小

939 阅读2分钟

比较应用程序版本对于人类来说是一项简单的任务。你可以立即判断哪个版本较新,例如 2.1.0 高于 1.0.0 和 2.0.0,但当我们尝试在 swift 代码中执行此操作时可能并不容易。今天来说几种常用的比较方式。

在苹果的应用程序中,版本号是由三个句点分隔的整数组成的字符串。第一个整数表示应用程序的主要修订,例如实现新功能或主要更改的修订。第二个整数表示实现不太突出的功能的修订版。第三个整数表示维护版本修订,比如修复 bug。

方法一

Foundation 框架中提供了字符串对比的函数 compare,利用这种方式可以直接将两个字符串版本进行比较,我写了一个字符串的扩展,来实现简单的对比:

extension String {
    func versionCompare(_ otherVersionString) -> ComparisonResult {
        return self.compare(otherVersion, options: .numeric)
    }
}

这个方法返回一个 ComparisonResult 对象,它有三个值:

  • orderedAscending:前者小于后者

  • orderedSame:两者相等

  • orderedDescending:前者大于后者

可以这样使用:

let result = "1.0.1".versionCompare("1.0.0")

switch result {
case .orderedAscending:
    print("1.0.1 < 1.0.0")
case .orderedSame:
    print("1.0.1 = 1.0.0")
case .orderedDescending:
    print("1.0.1 > 1.0.0")
}

最终打印:1.0.1 > 1.0.0

这种比较方式有个问题,只能对比相同位数的版本号,如果是一个两位,一个三位,比如 1.0 和 1.0.0 对比,就无法得出正确结果了。

方法二

要解决上边的问题,需要我们把这个扩展再改改:

extension String {
    func versionCompare(_ otherVersionString) -> ComparisonResult {
        var v1 = versionComponents()
        var v2 = otherVersion.versionComponents()
        let diff = v1.count - v2.count
        
        if diff == 0 {
            return self.compare(otherVersion, options: .numeric)
        }
        
        if diff > 0 {
            v2.append(contentsOf: (0..<diff).map { _ in "0" })
        } else {
            v1.append(contentsOf: (0..<abs(diff)).map { _ in "0" })
        }
        
        return v1.joined().compare(v2.joined())
    }
    
    func versionComponents() -> [String] {
        components(separatedBy: ".")
    }
}

1、首先把两个版本号按句点( . )拆分成数组

2、对比两个版本号的长度是否一致,如果一致,则利用 compare 函数直接对比

3、如果不一致,则把较短的版本号后面补 0

4、最后再用 compare 函数进行对比

最后我又写了一些测试用例,确保它能对比各种情况的版本号

print("0.1.1".versionCompare("0.1") == .orderedDescending) // true
print("0.1.0".versionCompare("0.1") == .orderedSame) // true
print("10.0.0".versionCompare("10") == .orderedSame) // true
print("10.0.1".versionCompare("10.0.1") == .orderedSame) // true
print("5.10.10".versionCompare("5.11.5") == .orderedAscending) // true
print("1.0.0".versionCompare("0.99.100") == .orderedDescending) // true
print("0.5.3".versionCompare("1.0.0") == .orderedAscending) // true
print("0.5.29".versionCompare("0.5.3") == .orderedDescending) // true
print("1.0".versionCompare("1.0.0.0.0.0") == .orderedSame) // true

最终以上测试用例全部符合预期。

本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!