2011-10-11 42 views
8

Hey Tôi đã tạo một tập lệnh Groovy sẽ trích xuất các số phiên bản của một số thư mục. Sau đó tôi muốn so sánh các số phiên bản và chọn số cao nhất.So sánh các chuỗi phiên bản trong groovy

Tôi có kịch bản của tôi để chạy qua các thư mục dir và sau đó tôi nhận được các phiên bản ở định dạng này: 02.2.02.01

Vì vậy, tôi có thể nhận được một cái gì đó như thế này:

  • 02.2.02.01
  • 02,2 .02.02
  • 02.2.03.01

tôi không có chúng như là một danh sách nhưng cũng giống như này:

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

Ngoài ra tôi đã thử nghiệm Groovy có thể so sánh chúng với toán tử > và có thể! Nhưng bây giờ tôi cần phải chọn một với phiên bản cao nhất

Trả lời

8

Điều này dường như làm việc

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

Dưới đây là một bộ đầy đủ các xét nghiệm. Bạn nên thêm một số chi tiết.

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' 

Chạy đoạn mã này và các bài kiểm tra trong giao diện điều khiển Groovy để xác minh rằng nó hoạt động

+0

+ 1 Cần lưu ý rằng phương thức 'mostRecentVersion' sẽ để lại tham số' versions' được sắp xếp sau khi nó được thực hiện (như 'List.sort' đột biến danh sách theo mặc định). Nếu điều này là không muốn, bạn có thể (trong groovy 1.8.1+) gọi: 'def sắp xếp = phiên bản.sort (false) {a, b ->' –

+0

@tim_yates Bạn không thể chỉ cho tôi tận hưởng thời điểm chiến thắng của tôi ? Ồ không, bạn phải nitpick. Tôi đã miễn cưỡng cập nhật câu trả lời của tôi để bao gồm đề xuất của bạn, cảm ơn :) –

+0

Hahaha ... xin lỗi ;-) * xáo trộn trở lại bàn làm việc của mình * –

2

Mine là ngắn nhất! 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

Nếu chúng ta sẽ cho câu trả lời ngắn nhất, điều này phải đến gần ;-)

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 bởi vì không có nhiều người tự hào tuyên bố sự thiếu hụt của họ trong một diễn đàn công cộng. Tốt cho bạn. –

4

Nếu bất cứ ai đang sử dụng Grails (ví dụ Grails 2.2.3), tôi nghĩ VersionComparator đã cung cấp chính xác những gì chúng tôi cần.

Nếu bạn không sử dụng Grails, bạn luôn có thể Google mã nguồn của lớp này.

Ví dụ về kiểm tra làm việc:

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 

Hope this helps.

+0

Cảm ơn, hộp cát Jenkins sẽ từ từ biến tôi thành một kẻ điên cuồng ... – mfeineis

0

Mã Tôi đang sử dụng với Jenkins ExtendedChoiceParameter (chịu được mảnh vỡ phi nguyên trong chuỗi phiên bả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

Dưới đây là một phiên bản sửa đổi một chút đóng góp của 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

Đây là một sửa đổi của câu trả lời của Tim có hai chuỗi phiên bản và trả về một boolean (true nếu đầu tiên là mới hơn thứ hai)

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

Tôi sử dụng gradle 4.1 trong Android Studio 3.0 Beta 7. Có VersionNumber.java (trong C: \ Users \ ssfang.gradle \ wrapper \ dists \ gradle-4.1-tất cả \ bzyivzo6n839fup2jbap0tjew \ gradle-4.1 \ src \ core \ org \ gradle \ util)

Ví dụ:

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

Các vấn đề liên quan