使用Iterable进行数字字符串排序<;组件>;在groovy中

使用Iterable进行数字字符串排序<;组件>;在groovy中,groovy,nexus,artifact,Groovy,Nexus,Artifact,我想从Iterable components对版本进行排序。当我在控制台中打印时,会显示以下结果: 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.rep

我想从
Iterable components
对版本进行排序。当我在控制台中打印时,会显示以下结果:

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()
}
import org.sonatype.nexus.repository.storage.Component
导入org.sonatype.nexus.repository.storage.Query
导入org.sonatype.nexus.repository.storage.StorageFacet
def repoName=“工件”
log.info(“删除存储库的组件:”+repoName)
def repo=repository.repositoryManager.get(repoName)
def tx=repo.facet(StorageFacet.txSupplier().get())
试一试{
开始
Iterable components=tx.findComponents(Query.builder()
.where('version<').param('1.1.0')
.build(),[repo])
tx.commit()
用于(组件c:组件){
log.info(“名称”+c.Name()+“版本”+c.Version())
}
}捕获(例外e){
warn(“事务失败{}”,例如toString())
tx.回滚()
}最后{
关闭
}

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

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'
另一个例子:

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
}

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

有些场景没有在示例输出中表示,因此需要确定需求是什么。
components.sort{it.version()}
是否产生了所需的顺序?您的标题是数字字符串排序,但您的输出显示
1.0.2
1.0.11
之后,这表明您的需求可能是字母排序。“它从何而来”——在Groovy中,如果闭包没有声明参数列表,闭包将接受1个可选参数,名为
it
<代码>{it.version()},
{it->it.version()}
{comp->comp.version()}
在功能上是等效的。“组件=组件.排序{it.size()}”-这是有效的Groovy,如果
components
中的所有元素都有一个名为
size
且不接受任何参数的方法,则在运行时不会抛出错误。我以为您想按版本排序,所以建议按
components=components.sort{it.version()}
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