以不寻常的方式在Groovy中对列表进行排序

bla*_*det 8 sorting groovy

我有一个列表,比方说[Cat, Dog, Cow, Horse],我希望按以下方式排序

  • 如果Cat在列表中它应该是第一个
  • 如果Cow在列表中它应该排在第二位
  • 其余元素应按字母顺序排列.

有什么建议如何在Groovy中完成?

Tom*_*Lin 7

蒂姆的回答非常聪明.我个人更喜欢使用列表操作,因为它生成的代码稍微容易阅读.

def highPriority = [ 'Cat', 'Cow' ]

def list = [ 'Armadillo', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cow', 'Cat' ]

def remainder = ( list - highPriority ).sort()

list.retainAll( highPriority )

list.sort{ highPriority.indexOf( it ) } + remainder
Run Code Online (Sandbox Code Playgroud)

这会给你两次牛.如果你不想重复,使用intersect非常简单.

def highPriority = [ 'Cat', 'Cow' ]

def list = [ 'Armadillo', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cow', 'Cat' ]

list.intersect( highPriority ).sort{ highPriority.indexOf( it ) } + ( list - highPriority ).sort()
Run Code Online (Sandbox Code Playgroud)


tim*_*tes 6

这应该这样做:

// Define our input list
def list = [ 'Armadillo', 'Cat', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cow' ]

// Define a closure that will do the sorting
def sorter = { String a, String b, List prefixes=[ 'Cat', 'Cow' ] ->
  // Get the index into order for a and b
  // if not found, set to being Integer.MAX_VALUE
  def (aidx,bidx) = [a,b].collect { prefixes.indexOf it }.collect {
    it == -1 ? Integer.MAX_VALUE : it
  }
  // Compare the two indexes.
  // If they are the same, compare alphabetically
  aidx <=> bidx ?: a <=> b
}

// Create a new list by sorting using our closure
def sorted = list.sort false, sorter

// Print it out
println sorted
Run Code Online (Sandbox Code Playgroud)

打印:

[Cat, Cow, Cow, Armadillo, Dog, Horse, Zebra]
Run Code Online (Sandbox Code Playgroud)

我评论它试图解释它所采取的每一步.通过在sorter闭包上添加默认前缀项作为可选参数,这意味着我们可以执行以下操作来更改默认值:

// Use Dog, Zebra, Cow as our prefix items
def dzc = list.sort false, sorter.rcurry( [ 'Dog', 'Zebra', 'Cow' ] )
println dzc
Run Code Online (Sandbox Code Playgroud)

然后打印列表排序为:

[Dog, Zebra, Cow, Cow, Armadillo, Cat, Horse]
Run Code Online (Sandbox Code Playgroud)