2011-10-11 31 views
8

Hola, he creado un script de Groovy que extraerá los números de versión de algunas carpetas. Entonces me gustaría comparar los números de versión y seleccionar el más alto.Comparar cadenas de versiones en groovy

obtuve mi secuencia de comandos para ejecutar a través de la carpeta dir en cuando me siento las versiones en este formato: 02.2.02.01

así que podría conseguir algo como esto:

  • 02.2.02.01
  • 02,2 .02.02
  • 02.2.03.01

no tengo como una lista, pero como esto:

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

También he probado que Groovy podría compararlos con el operador > y puede! Pero ahora tengo que seleccionar el que tiene la versión más alta

Respuesta

8

Esto parece funcionar

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

Aquí es un conjunto de pruebas inadecuadas. Deberías agregar un poco más.

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' 

Ejecutar este código y las pruebas en la consola maravilloso para verificar que funciona

+0

+ 1 Cabe señalar que el método 'mostRecentVersion' dejará el parámetro' versions' ordenado después de que se haya ejecutado (ya que 'List.sort' muta la lista de forma predeterminada). Si esto no se quiere, puedes (en Groovy 1.8.1+) llamar: 'def sorted = versions.sort (false) {a, b ->' –

+0

@tim_yates ¿No podrías dejarme disfrutar mi momento de triunfo? ? Oh no, tenías que criticar. He actualizado a regañadientes mi respuesta para incluir su sugerencia, gracias :) –

+0

Jajaja ... lo siento ;-) * se mezcla de nuevo a su escritorio * –

2

mina es la más corta! lol)

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

Si vamos a dar la respuesta más corto, esto debe acercarse ;-)

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 porque simplemente no hay muchas personas que orgullosamente proclamen su brevedad en un foro publico. Bien por usted. –

4

Si alguien está usando Grails (por ejemplo Grails 2.2.3), creo que ya VersionComparator proporciona exactamente lo que necesitamos.

Si no está utilizando Grails, siempre puede buscar en Google el código fuente de esta clase.

Ejemplo de pruebas de trabajo:

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 

Espero que esto ayude.

+0

Gracias, el arenero de Jenkins me convertiría lentamente en un lunático ... – mfeineis

0

El código que estoy utilizando con Jenkins ExtendedChoiceParameter (tolerantes a fragmentos no enteros en la cadena de versión)

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

Aquí hay una versión ligeramente modificada de la contribución de 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

Aquí hay una modificación de la respuesta de Tim que toma dos cadenas de versión y devuelve un valor booleano (verdadero si el primero es más nuevo que el segundo)

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

Uso gradle 4.1 en Android Studio 3.0 Beta 7. Hay VersionNumber.java (en C: \ Users \ ssfang.gradle \ wrapper \ dists \ gradle-4.1-all \ bzyivzo6n839fup2jbap0tjew \ Gradle-4,1 \ src \ core \ org \ Gradle \ util)

Por ejemplo:

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

Cuestiones relacionadas