2011-10-11 118 views
8

嘿,我已經創建了一個Groovy腳本,它將提取某些文件夾的版本號。然後我想比較版本號並選擇最高。比較groovy中的版本字符串

我得到了我的腳本通過目錄文件夾中運行,然後我得到的版本格式如下:02.2.02.01

所以我能得到這樣的:

  • 02.2.02.01
  • 02.2 .02.02
  • 02.2.03.01

我沒有他們的名單,但像這樣的:

baseDir.listFiles().each { file -> 
    def string = file.getName().substring(5, 15) 
    // do stuff 
} 

而且我測試過的Groovy可以將它們與>運營商比較,它可以!但現在我需要選擇一個具有最高版本

回答

8

這似乎工作

String mostRecentVersion(List versions) { 
    def sorted = versions.sort(false) { a, b -> 

    List verA = a.tokenize('.') 
    List verB = b.tokenize('.') 

    def commonIndices = Math.min(verA.size(), verB.size()) 

    for (int i = 0; i < commonIndices; ++i) { 
     def numA = verA[i].toInteger() 
     def numB = verB[i].toInteger() 
     println "comparing $numA and $numB" 

     if (numA != numB) { 
     return numA <=> numB 
     } 
    } 

    // If we got this far then all the common indices are identical, so whichever version is longer must be more recent 
    verA.size() <=> verB.size() 
    } 

    println "sorted versions: $sorted" 
    sorted[-1] 
} 

這裏是一個集不足的測試。你應該添加更多。

assert mostRecentVersion(['02.2.02.01', '02.2.02.02', '02.2.03.01']) == '02.2.03.01' 
assert mostRecentVersion(['4', '2']) == '4' 
assert mostRecentVersion(['4.1', '4']) == '4.1' 
assert mostRecentVersion(['4.1', '5']) == '5' 

運行該代碼和Groovy的控制檯的測試來驗證它的工作原理

+0

+ 1應該注意的是,'mostRecentVersion'方法會在'versions'參數被執行後對其進行排序(因爲'List.sort'默認情況下會突變列表)。如果這不是你想要的,你可以(在groovy 1.8.1+中)調用:'def sorted = versions.sort(false){a,b - >' –

+0

@tim_yates你不能讓我享受我的勝利時刻嗎? ?哦,不,你必須挑剔。我勉強更新我的答案,包括你的建議,謝謝:) –

+0

哈哈哈...對不起;-) *洗牌回他的辦公桌* –

2

礦是最短的!笑)

versions = versions.sort {a, b -> 
    def a1 = a.tokenize('.')*.toInteger(), b1 = b.tokenize('.')*.toInteger() 
    for (i in 0..<[a1.size(), b1.size()].min()) 
    if (a1[i] != b1[i]) return a1[i] <=> b1[i] 
    0 
} 
7

如果我們要爭取在最短的答案,這必須接近;-)

String mostRecentVersion(List versions) { 
    versions.sort(false) { a, b -> 
    [a,b]*.tokenize('.')*.collect { it as int }.with { u, v -> 
     [u,v].transpose().findResult{ x,y-> x<=>y ?: null } ?: u.size() <=> v.size() 
    } 
    }[-1] 
} 
+0

+1,因爲沒有多少人會自豪地宣稱他們的矮小公共論壇。對你有好處。 –

4

如果有人使用Grails(如Grails的2.2.3),我想VersionComparator已經提供了我們需要的東西。

如果您不使用Grails,您可以隨時Google Google此類的源代碼。

工作試驗的例子:

import org.codehaus.groovy.grails.plugins.VersionComparator 

assert ['1.13.4', '1.4.5'].sort(new VersionComparator()) == ['1.4.5', '1.13.4'] 
assert ['3.1.20', '3', '3.0.1', '3.1'].sort(new VersionComparator()) == ['3', '3.0.1', '3.1', '3.1.20'] 
assert ['02.2.02.02', '02.2.03.01', '02.2.02.01'].sort(new VersionComparator()) == ['02.2.02.01', '02.2.02.02', '02.2.03.01'] 
assert ['4', '2'].sort(new VersionComparator()) == ['2', '4'] 
assert ['4.1', '4'].sort(new VersionComparator()) == ['4', '4.1'] 
assert ['4.1', '5'].sort(new VersionComparator()) == ['4.1', '5'] 

assert new VersionComparator().compare('1.13.4', '1.4.5') > 0 
assert new VersionComparator().compare('1.4.5', '1.13.4') < 0 

希望這有助於。

+0

謝謝,詹金斯沙箱會讓我慢慢變成瘋子...... – mfeineis

0

我使用的代碼與詹金斯ExtendedChoiceParameter(版本字符串容忍非整片段)

def vers = ['none'] 
new File(this.getBinding().getVariable('dir')).eachDir() { dir -> dirs.add(dir.getName()) } 

vers.sort{x, y -> 
    def xa = x.tokenize('._-'); def ya = y.tokenize('._-') 
    def sz = Math.min(xa.size(), ya.size()) 
    for (int i = 0; i < sz; ++i) { 
    def xs = xa[i]; def ys = ya[i]; 
    if (xs.isInteger() && ys.isInteger()) { 
     def xn = xs.toInteger() 
     def yn = ys.toInteger() 
     if (xn != yn) { return xn <=> yn } 
    } else if (xs != ys) { 
     return xs <=> ys 
    } 
    } 

    return xa.size() <=> ya.size() 
}.reverse().join(',') 
1
String maxVersion(versions) { 
    versions.max { a, b -> 
     List verA = a.tokenize('.') 
     List verB = b.tokenize('.') 
     def commonIndices = Math.min(verA.size(), verB.size()) 
     for (int i = 0; i < commonIndices; ++i) { 
      def numA = verA[i].toInteger() 
      def numB = verB[i].toInteger() 
      if (numA != numB) { 
       return numA <=> numB 
      } 
     } 
     verA.size() <=> verB.size() 
    } 
} 
0

這裏是Nikita的貢獻略加修改:

List versions = [ '02.2.02.01', '02.2.02.02', '02.2.03.01'] 
String mostRecentVersion = versions.sort {a, b -> 
    def a1 = a.tokenize('.')*.toInteger(), b1 = b.tokenize('.')*.toInteger() 

    for (i in 0..<[a1.size(), b1.size()].min()){  
    if (a1[i] != b1[i]) { 
     return a1[i] <=> b1[i] 
    } 
    } 
}[-1] 

assert mostRecentVersion == '02.2.03.01' 
0

這是Tim的答案的修改,它接受兩個版本字符串並返回一個布爾值(如果第一個比第二個更新,則返回true)

String v1 = '02.2.01.02' 
String v2 = '02.2.06.02' 

boolean isMoreRecent(String a, String b) { 
    [a,b]*.tokenize('.')*.collect { it as int }.with { u, v -> 
     Integer result = [u,v].transpose().findResult{ x,y -> x <=> y ?: null } ?: u.size() <=> v.size() 
     return (result == 1) 
    } 
} 

assert !isMoreRecent(v1,v2) 
assert isMoreRecent(v2,v1)​ 
0

我在Android Studio 3.0 Beta 7中使用gradle 4.1。在C:\ Users \ ssfang.gradle \ wrapper \ dists \ gradle-4下有VersionNumber.java。1-所有\ bzyivzo6n839fup2jbap0tjew \ gradle這個-4.1 \ SRC \芯\有機\ gradle這個\ util的)

例如:

apply plugin: 'com.android.application' 

try{ // undocumented 
    println "${android.plugin.getSdkFolder().getAbsolutePath()}" 
    // Since 1.3.1 or 1.5.0? android studio version or android gradle plugin? 
    println "${android.getSdkDirectory().getAbsolutePath()}" 
}catch (ignored){ 
} 

// As of android gradle plugin v2.1.2 
println android.sdkDirectory.path 
println android.ndkDirectory.path 
def buildToolsVer = new File(android.sdkDirectory.path, 'build-tools').listFiles().collect{ VersionNumber.parse(it.getName()) }.sort() 
println buildToolsVer 
printf('%s, %s\n', buildToolsVer.head(), buildToolsVer.last().toString()) 

def String mostRecentVersion(List<String> versions) { 
// TreeMap<VersionNumber, String> verNum2StrMap = versions.collectEntries(new TreeMap(), { [VersionNumber.parse(it), it] }) 

// TreeMap<VersionNumber, String> verNum2StrMap = versions.inject(new TreeMap()) { memo, entry -> 
//  memo[VersionNumber.parse(entry)] = entry 
//  memo 
// } 

    TreeMap<VersionNumber, String> verNum2StrMap = versions.inject(new TreeMap()) { map, verStr -> 
     map << [(VersionNumber.parse(verStr)): verStr] 
    } 

    // println verNum2StrMap.lastEntry().value 
    verNum2StrMap.lastEntry().value 
} 

assert mostRecentVersion(['02.2.02.01', '02.2.02.02', '02.2.03.01']) == '02.2.03.01' 
assert mostRecentVersion(['4', '2']) == '4' 
assert mostRecentVersion(['4.1', '4']) == '4.1' 
assert mostRecentVersion(['4.1', '5']) == '5' 

android { 
    compileSdkVersion 25 
    buildToolsVersion "26.0.2" 
    defaultConfig { 
     applicationId "ss.xsigner" 
     minSdkVersion 14 
     targetSdkVersion 22 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
     setProperty("archivesBaseName", "xsigner") 
    } 
} 

-

enter image description here

enter image description here