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]
如果不是,那么实现相同结果的最接近/最常规的方法是什么,最好是在单个表达式中?
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]
如果不是,那么实现相同结果的最接近/最常规的方法是什么,最好是在单个表达式中?
您需要做的是按照您描述的方式将列表从六个元素转换为三个元素。即转换[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]
我不认为你可以使用多个分配来实现这一点。这是一个选项:
def list = [1,2,3,4,5,6]
def first = list[0]
def second = list[1]
def rest = list[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]
已经提供的使用with()
+ 闭包和collect()
+ 闭包的解决方案的变体。此解决方案仅使用带有可变参数的闭包:
def (first, second, rest) = { ... a -> a[0..1] + [a[2..-1]]} (1,2,3,4,5,6)
println first
println second
println rest