在groovy中按文件名排序数组

时间:2017-03-10 13:43:43

标签: sorting groovy

我正在尝试按照文件名对罐子列表进行排序:

def jars = ['app-5.0.0.jar', 'app-5.1.1.jar', 'app-5.2.0-9.jar', 'app-5.2.0-10.jar', 'app-5.2.0.jar', 'app-5.1.0.jar']
jars = jars.sort().reverse()
println jars

结果是:

[app-5.2.0.jar, app-5.2.0-9.jar, app-5.2.0-10.jar, app-5.1.1.jar, app-5.1.0.jar, app-5.0.0.jar]

但是,我对自然(可能更直观)排序更感兴趣,以接收这个排序列表:

[app-5.2.0-10.jar, app-5.2.0-9.jar, app-5.2.0.jar, app-5.1.1.jar, app-5.1.0.jar, app-5.0.0.jar]

有没有办法实现这个目标?

这是我目前的排序算法,但在我看来它太冗长了。但是,它确实做了我正在寻找的东西。版本的每个部分(主要,次要,维护,构建)都是独立评估的:

jars = jars.sort { a, b ->
    File fileA = new File(a)
    File fileB = new File(b)
    def partsA = fileA.name.findAll(/\d+/)
    def partsB = fileB.name.findAll(/\d+/)

    if (partsA[0] == null) partsA[0] = "0"
    if (partsB[0] == null) partsB[0] = "0"
    if (partsA[0].toInteger() < partsB[0].toInteger()) {
        println "${partsA[0]} < ${partsB[0]}"
        return -1
    } else if (partsA[0].toInteger() > partsB[0].toInteger()) {
        println "${partsA[0]} > ${partsB[0]}"
        return 1
    } else {
        if (partsA[1] == null) partsA[1] = "0"
        if (partsB[1] == null) partsB[1] = "0"
        if (partsA[1].toInteger() < partsB[1].toInteger()) {
            println "${partsA[1]} < ${partsB[1]}"
            return -1
        } else if (partsA[1].toInteger() > partsB[1].toInteger()) {
            println "${partsA[1]} > ${partsB[1]}"
            return 1
        } else {
            if (partsA[2] == null) partsA[2] = "0"
            if (partsB[2] == null) partsB[2] = "0"
            if (partsA[2].toInteger() < partsB[2].toInteger()) {
                println "${partsA[2]} < ${partsB[2]}"
                return -1
            } else if (partsA[2].toInteger() > partsB[2].toInteger()) {
                println "${partsA[2]} > ${partsB[2]}"
                return 1
            } else {
                if (partsA[3] == null) partsA[3] = "0"
                if (partsB[3] == null) partsB[3] = "0"
                if (partsA[3].toInteger() < partsB[3].toInteger()) {
                    println "${partsA[3]} < ${partsB[3]}"
                    return -1
                } else if (partsA[3].toInteger() > partsB[3].toInteger()) {
                    println "${partsA[3]} > ${partsB[3]}"
                    return 1
                } else {
                    println "${partsA[3]} = ${partsB[3]}"
                    return 0
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:3)

不得不试试这个:

def jars = ['app-5.0.0.jar', 'app-5.1.1.jar', 'app-5.2.0-9.jar', 'app-5.2.0-10.jar', 'app-5.2.0.jar', 'app-5.1.0.jar', 'app-1.0.jar', 'app-0.10.jar']
jars = jars.sort{ -it.findAll( /\d+/ ).join().toInteger() }
println jars

获取:

[app-5.2.0-10.jar, app-5.2.0-9.jar, app-5.2.0.jar, app-5.1.1.jar, app-5.1.0.jar, app-5.0.0.jar, app-1.0.jar, app-0.10.jar]

或处理大型补丁版本的更全面的版本:

def jars = ['app-5.0.0.jar', 'app-5.1.1.jar', 'app-5.2.0-9.jar', 'app-5.2.0-10.jar', 'app-5.2.0.jar', 'app-5.1.0.jar', 'app-5.1.1-172.jar']

jars.sort{ a, b -> 
    def aList = a.findAll(/\d+/)
    def bList = b.findAll(/\d+/)

    for ( int i = 0 ; i < aList.size() ; i++ ) {
        def aVal = aList[i] ? aList[i].toInteger() : 0
        def bVal = bList[i] ? bList[i].toInteger() : 0
        if ( aVal <=> bVal ) { // only return if non-zero i.e. not equal
            return aVal <=> bVal
        }
    }

    bList.size() > aList.size() ? -1 : 0 // all facets match up to now, if b has additional parts it must be later version
}

println jars.reverse()

获取:

[app-5.2.0-10.jar, app-5.2.0-9.jar, app-5.2.0.jar, app-5.1.1-172.jar, app-5.1.1.jar, app-5.1.0.jar, app-5.0.0.jar]

答案 1 :(得分:1)

这样的事情怎么样:

for(int i = 0; i<no; i++){
    printf("What is student %d name?\n", i+1);
    scanf(" %[^\n]", &p[i].name); // mutate the ith student in p
    // ...
}

输出:

def jars = ['app-5.0.0.jar', 'app-5.1.1.jar', 'app-5.2.0-9.jar', 'app-5.2.0-10.jar', 'app-5.2.0.jar', 'app-5.1.0.jar', 'app-5.1.1-172.jar']

// it is probably sufficient to just choose a "high enough" number
// (e.g. 10) instead of resolving max digits.
def maxDigits = jars*.findAll(/\d+/).flatten()*.size().max()

// sort the strings consisting of left-padded version numbers
// e.g. sorting string for 'app-5.1.1-172.jar' is '  5  1  1172'
jars.sort{ it.findAll(/\d+/)*.padLeft(maxDigits).join() }

println 'max digits: ' + maxDigits
println jars.reverse()