Swift에서 두 버전 문자열 비교
두 가지 앱 버전 문자열 (예 : "3.0.1"및 "3.0.2")이 있습니다.
Swift를 사용하여 어떻게 비교할 수 있습니까?
내 문자열을 NSStrings로 변환해야했습니다.
if storeVersion.compare(currentVersion, options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedDescending {
println("store version is newer")
}
스위프트 3
let currentVersion = "3.0.1"
let storeVersion = "3.0.2"
if storeVersion.compare(currentVersion, options: .numeric) == .orderedDescending {
print("store version is newer")
}
NSString으로 캐스팅 할 필요가 없습니다. Swift 3의 String 객체는 아래와 같이 버전을 비교할만큼 강력합니다.
let version = "1.0.0"
let targetVersion = "0.5.0"
version.compare(targetVersion, options: .numeric) == .orderedSame // false
version.compare(targetVersion, options: .numeric) == .orderedAscending // false
version.compare(targetVersion, options: .numeric) == .orderedDescending // true
그러나 위의 샘플은 추가 0이있는 버전을 다루지 않습니다. (예 : "1.0.0"& "1.0")
그래서 저는 Swift를 사용하여 버전 비교를 처리하기 위해 String에서 모든 종류의 확장 메서드를 만들었습니다. 내가 말한 여분의 0은 매우 간단하며 예상대로 작동합니다.
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(lessThan: "99.0.0"))
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(equalTo: UIDevice.current.systemVersion))
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(greaterThan: "3.5.99"))
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(lessThanOrEqualTo: "13.5.99"))
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(greaterThanOrEqualTo: UIDevice.current.systemVersion))
XCTAssertTrue("0.1.1".isVersion(greaterThan: "0.1"))
XCTAssertTrue("0.1.0".isVersion(equalTo: "0.1"))
XCTAssertTrue("10.0.0".isVersion(equalTo: "10"))
XCTAssertTrue("10.0.1".isVersion(equalTo: "10.0.1"))
XCTAssertTrue("5.10.10".isVersion(lessThan: "5.11.5"))
XCTAssertTrue("1.0.0".isVersion(greaterThan: "0.99.100"))
XCTAssertTrue("0.5.3".isVersion(lessThanOrEqualTo: "1.0.0"))
XCTAssertTrue("0.5.29".isVersion(greaterThanOrEqualTo: "0.5.3"))
내 샘플 확장 저장소에서 원하는 모든 것을 살펴보고 라이센스없이 원하는대로 가져 가십시오.
https://github.com/DragonCherry/VersionCompare
Swift 3 버전
let storeVersion = "3.14.10"
let currentVersion = "3.130.10"
extension String {
func versionToInt() -> [Int] {
return self.components(separatedBy: ".")
.map { Int.init($0) ?? 0 }
}
}
//true
storeVersion.versionToInt().lexicographicallyPrecedes(currentVersion.versionToInt())
Swift 2 버전 비교
let storeVersion = "3.14.10"
let currentVersion = "3.130.10"
extension String {
func versionToInt() -> [Int] {
return self.componentsSeparatedByString(".")
.map {
Int.init($0) ?? 0
}
}
}
// true
storeVersion.versionToInt().lexicographicalCompare(currentVersion.versionToInt())
다음은 나를 위해 일하고 있습니다.
extension String {
static func ==(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedSame
}
static func <(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedAscending
}
static func <=(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedAscending || lhs.compare(rhs, options: .numeric) == .orderedSame
}
static func >(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedDescending
}
static func >=(lhs: String, rhs: String) -> Bool {
return lhs.compare(rhs, options: .numeric) == .orderedDescending || lhs.compare(rhs, options: .numeric) == .orderedSame
}
}
"1.2.3" == "1.2.3" // true
"1.2.3" > "1.2.3" // false
"1.2.3" >= "1.2.3" // true
"1.2.3" < "1.2.3" // false
"1.2.3" <= "1.2.3" // true
"3.0.0" >= "3.0.0.1" // false
"3.0.0" > "3.0.0.1" // false
"3.0.0" <= "3.0.0.1" // true
"3.0.0.1" >= "3.0.0.1" // true
"3.0.1.1.1.1" >= "3.0.2" // false
"3.0.15" > "3.0.1.1.1.1" // true
"3.0.10" > "3.0.100.1.1.1" // false
"3.0.1.1.1.3.1.7" == "3.0.1.1.1.3.1" // false
"3.0.1.1.1.3.1.7" > "3.0.1.1.1.3.1" // true
"3.14.10" == "3.130.10" // false
"3.14.10" > "3.130.10" // false
"3.14.10" >= "3.130.10" // false
"3.14.10" < "3.130.10" // true
"3.14.10" <= "3.130.10" // true
스위프트 4
let current = "1.3"
let appStore = "1.2.9"
let versionCompare = current.compare(appStore, options: .numeric)
if versionCompare == .orderedSame {
print("same version")
} else if versionCompare == .orderedAscending {
// will execute the code here
print("ask user to update")
} else if versionCompare == .orderedDescending {
// execute if current > appStore
print("don't expect happen...")
}
때때로 storeVersion의 길이가 currentVersion의 길이와 같지 않습니다. 예를 들어 storeVersion이 3.0.0
이지만 버그를 수정하고 이름을 3.0.0.1
.
func ascendingOrSameVersion(minorVersion smallerVersion:String, largerVersion:String)->Bool{
var result = true //default value is equal
let smaller = split(smallerVersion){ $0 == "." }
let larger = split(largerVersion){ $0 == "." }
let maxLength = max(smaller.count, larger.count)
for var i:Int = 0; i < maxLength; i++ {
var s = i < smaller.count ? smaller[i] : "0"
var l = i < larger.count ? larger[i] : "0"
if s != l {
result = s < l
break
}
}
return result
}
Swift 3을 사용하면 옵션이 숫자로 설정된 비교 기능을 사용하여 애플리케이션 버전 문자열을 비교할 수 있습니다.
작동 방식에 대한 Objective-C 예제는 Apple Developers의 문서에서이 문자열 프로그래밍 가이드를 읽어보십시오 .
나는 https://iswift.org/playground 에서 이것을 시도했습니다.
print("2.0.3".compare("2.0.4", options: .numeric))//orderedAscending
print("2.0.3".compare("2.0.5", options: .numeric))//orderedAscending
print("2.0.4".compare("2.0.4", options: .numeric))//orderedSame
print("2.0.4".compare("2.0.3", options: .numeric))//orderedDescending
print("2.0.5".compare("2.0.3", options: .numeric))//orderedDescending
print("2.0.10".compare("2.0.11", options: .numeric))//orderedAscending
print("2.0.10".compare("2.0.20", options: .numeric))//orderedAscending
print("2.0.0".compare("2.0.00", options: .numeric))//orderedSame
print("2.0.00".compare("2.0.0", options: .numeric))//orderedSame
print("2.0.20".compare("2.0.19", options: .numeric))//orderedDescending
print("2.0.99".compare("2.1.0", options: .numeric))//orderedAscending
도움이 되었기를 바랍니다.
라이브러리 사용을 좋아한다면이 라이브러리를 사용하고 바퀴를 재발 명하지 마십시오. https://github.com/zenangst/Versions
'String.compare'메소드를 사용하여 수행 할 수 있습니다. ComparisonResult를 사용하여 버전이 더 크거나 같거나 적은시기를 식별하십시오.
예:
"1.1.2".compare("1.1.1").rawValue -> ComparisonResult.orderedDescending
"1.1.2".compare("1.1.2").rawValue -> ComparisonResult.orderedSame
"1.1.2".compare("1.1.3").rawValue -> ComparisonResult.orderedAscending
이를 위해 작은 Swift 3 클래스를 작성했습니다.
class VersionString: NSObject {
// MARK: - Properties
var string = ""
override var description: String {
return string
}
// MARK: - Initialization
private override init() {
super.init()
}
convenience init(_ string: String) {
self.init()
self.string = string
}
func compare(_ rhs: VersionString) -> ComparisonResult {
return string.compare(rhs.string, options: .numeric)
}
static func ==(lhs: VersionString, rhs: VersionString) -> Bool {
return lhs.compare(rhs) == .orderedSame
}
static func <(lhs: VersionString, rhs: VersionString) -> Bool {
return lhs.compare(rhs) == .orderedAscending
}
static func <=(lhs: VersionString, rhs: VersionString) -> Bool {
return lhs.compare(rhs) == .orderedAscending || lhs.compare(rhs) == .orderedSame
}
static func >(lhs: VersionString, rhs: VersionString) -> Bool {
return lhs.compare(rhs) == .orderedDescending
}
static func >=(lhs: VersionString, rhs: VersionString) -> Bool {
return lhs.compare(rhs) == .orderedDescending || lhs.compare(rhs) == .orderedSame
}
}
let v1 = VersionString("1.2.3")
let v2 = VersionString("1.2.3")
print("\(v1) == \(v2): \(v1 == v2)") // 1.2.3 == 1.2.3: true
print("\(v1) > \(v2): \(v1 > v2)") // 1.2.3 > 1.2.3: false
print("\(v1) >= \(v2): \(v1 >= v2)") // 1.2.3 >= 1.2.3: true
print("\(v1) < \(v2): \(v1 < v2)") // 1.2.3 < 1.2.3: false
print("\(v1) <= \(v2): \(v1 <= v2)") // 1.2.3 <= 1.2.3: true
@DragonCherry 솔루션은 훌륭합니다!
그러나 불행히도 버전이 다음과 같을 때는 작동하지 않습니다 1.0.1.2
(존재해서는 안되지만 일이 발생합니다).
확장 기능을 변경하고 모든 사례를 다루기 위해 테스트를 개선했습니다. 또한 버전 문자열에서 불필요한 문자를 모두 제거하는 확장을 만들었습니다 v1.0.1.2
.
다음 요점에서 모든 코드를 확인할 수 있습니다.
- 문자열 확장-https: //gist.github.com/endy-s/3791fe5c856cccaabff331fd49356dbf
- 테스트-https: //gist.github.com/endy-s/7cacaa730bf9fd5abf6021e58e962191
누구에게나 도움이되기를 바랍니다 :)
를 사용하는 NSString
것이 올바른 방법이지만 여기에 재미를위한 재단이 아닌 시도가 있습니다.
let storeVersion = "3.14.10"
let currentVersion = "3.130.10"
func versionToArray(version: String) -> [Int] {
return split(version) {
$0 == "."
}.map {
// possibly smarter ways to do this
$0.toInt() ?? 0
}
}
storeVersion < currentVersion // false
// true
lexicographicalCompare(versionToArray(storeVersion), versionToArray(currentVersion))
다음은 간단한 신속한 구조체입니다.
public struct VersionString: Comparable {
public let rawValue: String
public init(_ rawValue: String) {
self.rawValue = rawValue
}
public static func == (lhs: VersionString, rhs: VersionString) -> Bool {
return lhs.rawValue.compare(rhs.rawValue, options: .numeric) == .orderedSame
}
public static func < (lhs: VersionString, rhs: VersionString) -> Bool {
return lhs.rawValue.compare(rhs.rawValue, options: .numeric) == .orderedAscending
}
}
이것은 어떤가요:
class func compareVersion(_ ver: String, to toVer: String) -> ComparisonResult {
var ary0 = ver.components(separatedBy: ".").map({ return Int($0) ?? 0 })
var ary1 = toVer.components(separatedBy: ".").map({ return Int($0) ?? 0 })
while ary0.count < 3 {
ary0.append(0)
}
while ary1.count < 3 {
ary1.append(0)
}
let des0 = ary0[0...2].description
let des1 = ary1[0...2].description
return des0.compare(des1, options: .numeric)
}
및 테스트 :
func test_compare_version() {
XCTAssertEqual(compareVersion("1.0.0", to: "1.0.0"), .orderedSame)
XCTAssertEqual(compareVersion("1.0.0", to: "1.0."), .orderedSame)
XCTAssertEqual(compareVersion("1.0.0", to: "1.0"), .orderedSame)
XCTAssertEqual(compareVersion("1.0.0", to: "1."), .orderedSame)
XCTAssertEqual(compareVersion("1.0.0", to: "1"), .orderedSame)
XCTAssertEqual(compareVersion("1.0.0", to: "1.0.1"), .orderedAscending)
XCTAssertEqual(compareVersion("1.0.0", to: "1.1."), .orderedAscending)
XCTAssertEqual(compareVersion("1.0.0", to: "1.1"), .orderedAscending)
XCTAssertEqual(compareVersion("1.0.0", to: "2."), .orderedAscending)
XCTAssertEqual(compareVersion("1.0.0", to: "2"), .orderedAscending)
XCTAssertEqual(compareVersion("1.0.0", to: "1.0.0"), .orderedSame)
XCTAssertEqual(compareVersion("1.0.", to: "1.0.0"), .orderedSame)
XCTAssertEqual(compareVersion("1.0", to: "1.0.0"), .orderedSame)
XCTAssertEqual(compareVersion("1.", to: "1.0.0"), .orderedSame)
XCTAssertEqual(compareVersion("1", to: "1.0.0"), .orderedSame)
XCTAssertEqual(compareVersion("1.0.1", to: "1.0.0"), .orderedDescending)
XCTAssertEqual(compareVersion("1.1.", to: "1.0.0"), .orderedDescending)
XCTAssertEqual(compareVersion("1.1", to: "1.0.0"), .orderedDescending)
XCTAssertEqual(compareVersion("2.", to: "1.0.0"), .orderedDescending)
XCTAssertEqual(compareVersion("2", to: "1.0.0"), .orderedDescending)
XCTAssertEqual(compareVersion("1.0.0", to: "0.9.9"), .orderedDescending)
XCTAssertEqual(compareVersion("1.0.0", to: "0.9."), .orderedDescending)
XCTAssertEqual(compareVersion("1.0.0", to: "0.9"), .orderedDescending)
XCTAssertEqual(compareVersion("1.0.0", to: "0."), .orderedDescending)
XCTAssertEqual(compareVersion("1.0.0", to: "0"), .orderedDescending)
XCTAssertEqual(compareVersion("", to: "0"), .orderedSame)
XCTAssertEqual(compareVersion("0", to: ""), .orderedSame)
XCTAssertEqual(compareVersion("", to: "1"), .orderedAscending)
XCTAssertEqual(compareVersion("1", to: ""), .orderedDescending)
XCTAssertEqual(compareVersion("1.0.0", to: "1.0.0.9"), .orderedSame)
XCTAssertEqual(compareVersion("1.0.0.9", to: "1.0.0"), .orderedSame)
}
참조 URL : https://stackoverflow.com/questions/27932408/compare-two-version-strings-in-swift
'programing' 카테고리의 다른 글
두 NSDate 객체의 차이점 — 결과도 NSDate (0) | 2021.01.16 |
---|---|
오전 / 오후 형식으로 시간을 얻는 방법 iphone NSDateFormatter? (0) | 2021.01.16 |
전체 파일을 메모리로 읽지 않고 파일의 줄 수를 계산합니까? (0) | 2021.01.16 |
Android에서보기를 비트 맵으로 변환 (0) | 2021.01.16 |
사이트에 사진을 업로드하고 저장하는 가장 좋은 방법은 무엇입니까? (0) | 2021.01.16 |