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]
如果没有,最接近/最常用的方法是什么,最好是单表达式?
答案 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