2011-10-11 219 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