2014-09-27 73 views
4

Groovy中的列表解構(多重賦值)可用於將值綁定到列表中的變量。例如:獲取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] 

如果沒有,什麼是實現同樣的結果最接近/ grooviest方式,最好是在單一的表達?

回答

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] 
0

我不認爲你可以使用多個任務來實現這一點。這裏有一個選項:

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

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

是的,謝謝你的回答。我應該更清楚的問題(我現在已經更新了)。我正在尋找一種單一的表達/解構方法,它可以很容易地推廣,使得def(a,b,c ... )= [...] – kunal 2014-09-27 12:28:47

+0

@kunal我明白你想要什麼,但這是不可能的要做到這一點,因爲多重賦值語法只會將一個列表元素分配給每個變量 – 2014-09-27 12:41:17

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]​ 
0

在解決方案的變化已經提供的標準使用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