【问题标题】:Numeric string sorting using Iterable<Component> in groovy在 groovy 中使用 Iterable<Component> 进行数字字符串排序
【发布时间】:2021-03-16 15:11:13
【问题描述】:

我想从Iterable&lt;Component&gt; components 中排序版本。 Нow 当我在控制台中打印时,它会显示以下结果:

artifact 1.0.1
artifact 1.0.10
artifact 1.0.11
artifact 1.0.12
artifcat 1.0.2
artifcat 1.0.3
artifcat 1.0.4

这是我的代码

import org.sonatype.nexus.repository.storage.Component
import org.sonatype.nexus.repository.storage.Query
import org.sonatype.nexus.repository.storage.StorageFacet

def repoName = "artifact"

log.info("delete components for repository: " + repoName)


def repo = repository.repositoryManager.get(repoName)
def tx = repo.facet(StorageFacet).txSupplier().get()
try {
tx.begin()
    Iterable<Component> components = tx.findComponents(Query.builder()
      .where('version < ').param('1.1.0')
      .build(), [repo])
    tx.commit()
    
    for(Component c : components) {
        log.info("Name " + c.name() + " Version" + c.version())
    }
} catch (Exception e) {
    log.warn("Transaction failed {}", e.toString())
    tx.rollback()
} finally {
    tx.close()
}

【问题讨论】:

  • 有些场景没有在您的示例输出中表示,以确定要求是什么。 components.sort {it.version()} 是否产生所需的订单?
  • 您的标题显示为 数字字符串排序,但您的输出显示 1.0.2coming after 1.0.11 这表明您的要求可能是 alpha 排序。
  • "它从哪里来的" - 在 Groovy 中,如果闭包没有声明参数列表,则闭包将接受 1 个可选参数,名为 it{ it.version() }{ it -&gt; it.version() }{ comp -&gt; comp.version() } 在功能上是等效的。
  • "components = components.sort { it.size() }" - 这是有效的 Groovy,如果 components 中的所有元素都有一个名为size 不接受任何参数。
  • 我以为你想按版本排序,所以我建议components = components.sort { it.version() }

标签: groovy nexus artifact


【解决方案1】:

可以按版本进行一些简单的排序,如下所示:

def components = []
'''\
artifact 1.2.1
artifact 1.0.1
artifact 1.0.10
artifact 2.0.10
artifact 1.0.11
artifact 1.0.12
artifact 1.4.12
artifcat 1.0.2
artifcat 1.0.3
artifcat 1.0.4'''.splitEachLine( ' ' ){ name, version ->
  components << [ name:name, version:version ]
}

// augment each component with numeric represenation of version
components.each{
  it.versionNumeric = it.version.split( /\./ )*.toInteger().reverse().withIndex().sum{ num, pow -> 100.power( pow ) * num }
}

components.sort{ it.versionNumeric }*.version.join '\n'

打印

1.0.1
1.0.2
1.0.3
1.0.4
1.0.10
1.0.11
1.0.12
1.2.1
1.4.12
2.0.10

【讨论】:

    【解决方案2】:

    另一个例子:

    def components = '''\
    artifact 1.2.1
    artifact 1.0.1
    artifact 1.0.10
    artifact 2.0.10
    artifact 10.2
    artifact 1.0.11
    artifact 1.0.12
    artifact 1.4.12
    artifcat 1.0.2
    artifcat 1.0.3
    artifcat 1.0.4
    artifact 1.0.4.2'''.readLines()*.tokenize(' ').collect { name, version ->
      [name: name, version: version]
    }
    
    def sorted = components.sort { a, b ->
      def f = { it.version.tokenize('.')*.toInteger() }
      [f(a), f(b)].transpose().findResult { ai, bi -> 
        ai <=> bi ?: null 
      } ?: a.version <=> b.version
    }
    
    sorted.each { c -> 
        println c.version
    }
    

    哪个打印:

    ─➤ groovy solution.groovy
    1.0.1
    1.0.2
    1.0.3
    1.0.4
    1.0.4.2
    1.0.10
    1.0.11
    1.0.12
    1.2.1
    1.4.12
    2.0.10
    10.2
    

    请注意,此解决方案还(至少或多或少)处理具有不同数量元素的版本,例如 10.21.0.4.2

    【讨论】:

      猜你喜欢
      • 2012-08-29
      • 2013-12-21
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 2012-11-14
      • 1970-01-01
      • 2021-03-17
      • 2012-07-06
      相关资源
      最近更新 更多