2016-07-11 31 views
0

在Ruby中,我一直在尋找一個優雅的單行語句來爲通過方法調用從數組返回的多個變量(但不是全部)分配一個共同的值。通過並行賦值將變量的子集賦給共同的值

目標的關鍵是兩行語句轉化,如:

a, x = 1, 2 
y = x 

分爲:a, x, y = 1, 2, 2沒有硬編碼的重複值。所以a得到一個值(1),而xy都有共同的值(2)。

要延長到例如一個用例,假設而不是直接分配值1, 2,我們通過從一個方法調用返回數組分配我們的價值觀:

a, x = 7.divmod 5 # array [1,2] is unpacked via parallel assignment 
y = x 

這樣做的結果是相同的第一個代碼示例,我們可以用變量替換整數以使分配動態化。

你能推薦一些技巧來將這個任務合併到一行中嗎?這是到目前爲止,我已經考慮了幾個選項:

n = 7 # number 
m = 5 # divided by 

# Option 1) Store array via inline-variable assignment and append last 
#   element to align values for the parallel assignment 
a, x, y = (t = n.divmod(m)) << t[-1] 

# Option 2) Use Array#values_at to repeat some elements 
a, x, y = n.divmod(m).values_at 0,1,1 

對於這些新的並行任務,this SO post包括標準的使用。

+0

我不知道,你可以做你問什麼。你可以做的一件事是壓縮你的'='的右邊是使用'*'運算符,它將一個數組的副本附加到它自己。例如,'[1,2] * 3 => [1,2,1,2,1,2]'。因此'a,b,c = [1] + [2] * 2'相當於'a,b,c = 1,2,2'。我不能真正想到很多情況下這樣做會更快,但如果你想要它,它就在那裏。 – lwassink

+0

你想要單行還是想要可讀代碼? –

+0

@Sergio,理想情況下都是。這可能是單線選項增加了比它們在這裏值得的複雜性。邊緣案例的挑戰偶爾也會挖掘新技術,所以我認爲我會發布。 – Cam

回答

1

另一種選擇

a, x, y = 7.divmod(5).tap {|a| a << a[-1]} 
+0

老實說,額外的分配看起來最好的選擇。當然比這個更好。 :) –

+0

@nikkypx使用'#tap'是對我的第一個選擇的改進,因爲它沒有在範圍中引入新的變量。它也可以使用像'#fill'這樣的方法(它不會在其代碼塊中提供自引用):'a,x,y,z = 7.divmod(5).tap {| a | a.fill(2,2){a [1]}}' – Cam