在Groovy中的多个赋值中获取列表的尾部

时间:2014-09-27 11:48:08

标签: list groovy destructuring

Groovy中的列表解构(多重赋值)可用于将值绑定到列表中的变量。例如:

def (first, second, third) = [1,2,3,4,5,6]
assert third == 3

是否有一种语法方法可以实现以下目标:

def (first, second, <rest>) = [1,2,3,4,5,6]
assert ​rest​ == [3,4,5,6]

如果没有,最接近/最常用的方法是什么,最好是单表达式?

4 个答案:

答案 0 :(得分:3)

您需要做的是按照您描述的方式将列表从六个元素转换为三个元素。即将[1,2,3,4,5,6]转换为[1,2,[3,4,5,6]]。您可能还希望将其调整为任意数量的元素。

以下是一种解决方案,其中将新方法reduce添加到List,以建议的方式转换列表:

List.metaClass.reduce = { int size -> delegate[0..size-2] + [delegate[size-1..-1]] }

def (first, second, rest) = [1,2,3,4,5,6].reduce(3)
assert first == 1
assert second == 2
assert rest == [3,4,5,6]

编辑:昨晚,当我睡觉时,我考虑使用with来实现这一目标。它与上面的想法相同,但由于逻辑内联,因此更加神秘(不太可读)。

def (first, second, rest) = [1,2,3,4,5,6].with { it[0..1] + [it[2..-1]] }
assert first == 1
assert second == 2
assert rest == [3,4,5,6]

答案 1 :(得分:1)

我认为你不能使用多个任务来实现这一目标。这是一个选项:

def list = [1,2,3,4,5,6]

def first = list[0]
def second = list[1]
def rest = list[2..-1]

答案 2 :(得分:1)

我能达到的最近的是:

选项1:如果使用metaClass玩弄听起来是个好主意:

List.metaClass.destructure = { ...n->
   n.collect { delegate[it] }
}

def (a, b, rest) = [1,2,3,4].destructure(0, 1, 2..-1)

选项2.否则,这是一个很好的老救援方法:

def destructure (list,...n) {
    n.collect { list[it] }
}

def (a, b, rest) = destructure([1,2,3,4], 0, 1, 2..-1)

选项3.内联但不太丑陋的解决方案

def (a, b, rest) = [0, 1, 2..-1].collect { [1,2,3,4][it] }

以上所有都通过了标准

assert rest​ == ​[3,4]​

答案 3 :(得分:0)

已提供的使用with() +闭包和collect() +闭包的解决方案的变体。此解决方案仅使用带有varargs的闭包:

def (first, second, rest) = { ... a -> a[0..1] + [a[2..-1]]} (1,2,3,4,5,6)

println first
println second
println rest