2017-08-15 34 views
0

所以我一直在努力尋找解決方案。在Ruby中添加參數到陣列產品功能

我需要一個方法,將採取任何數量的陣列,我需要收集的product

1數組:

return [A, B, C] # => [A, B, C] 

2數組:

return [A, B, C].product([1, 2, 3]) # => [[A, 1], [A, 2], [A, 3], [B, 1] ... [C, 3]] 

3數組:

return [A, B, C].product([1, 2, 3,],[x, y, z]) # => [[A, 1, x], [A, 1, y], ... [C, 3, z]] 

所以我的當前的解決方案是這種情況下開關,它是功能性的,但是不方便。

case options.count 
when 1 
    options[0].values 
when 2 
    options[0].values.product(options[1].values) 
when 3 
    options[0].values.product(options[1].values, 
          options[2].values) 
when 4 
    options[0].values.product(options[1].values, 
          options[2].values, 
          options[3].values) 
end 

我在找的是一種程序上或遞歸返回未知數量的數組產品。輸出需要像上面的數組一樣。

我已經試過:

array = options[0].values 
options.each_with_index do |option, i| 
    array = array.product(option.values) if i > 0 
end 
return array 

但它返回:

[[[A, 1], x], [[A, 1], y], [[A, 1], z], [[A, 2], x], ... [[C, 3], z]] 

哪些羣體不正確的值。

+0

我有點困惑關於這個問題。你不是在描述「產品」方法嗎?你在尋找什麼不同?也許我是誤解。如果您要查找的是[1,2] .product([3,4],[5,6])#=> [[1,3,5],[1,3,6],[ 1,4,5],[1,4,6],...]'這正是'產品'的作用 –

+0

我有一個可變數量的數組,通過'產品'方法,並不知道' *數組的前綴將其分隔爲不同的參數,而不是數組成爲第一個參數。 – Okomikeruko

回答

2

希望這有助於

a = [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]] 
a[0].product(*a[1..a.length]) 
#=> [["a", "d", "g"], ["a", "d", "h"], ["a", "d", "i"], ["a", "e", "g"], ["a", "e", "h"], ["a", "e", "i"], ["a", "f", "g"], ["a", "f", "h"], ["a", "f", "i"], ["b", "d", "g"], ["b", "d", "h"], ["b", "d", "i"], ["b", "e", "g"], ["b", "e", "h"], ["b", "e", "i"], ["b", "f", "g"], ["b", "f", "h"], ["b", "f", "i"], ["c", "d", "g"], ["c", "d", "h"], ["c", "d", "i"], ["c", "e", "g"], ["c", "e", "h"], ["c", "e", "i"], ["c", "f", "g"], ["c", "f", "h"], ["c", "f", "i"]] 
# or 
a.slice!(0).product(*a) #Note: this mutates array. 
# or 
a[0].product(*a.drop(1)) # suggested by Cary Swoveland 
+0

考慮使用'a.first'而不是'a [0]':) –

+0

@engineersmnky:沒有得到最後的部分 - 它沒有影響?我認爲''a.shift'稍後會將它改爲'* a';像'a.slice!(0)'一樣。沒有? – kiddorails

+0

@kiddorails我的道歉應該是'def multi_product(* a); a.shift.product(* A); end'然後稱爲'multi_product(* a)',因爲splat會創建一個新的'Array',原來的'a'不會被修改。此外,你可以使用'def multi_product(a);首先,* rest = a;第一。產品(* rest); end' – engineersmnky

5

如何像:

def multi_product(base, *args) 
    base.product(*args) 
end 

結果:

multi_product(['A', 'B', 'C']) 
# => [["A"], ["B"], ["C"]] 
multi_product(['A', 'B', 'C'], [1, 2, 3]) 
# => [["A", 1], ["A", 2], ["A", 3], ["B", 1], ["B", 2], ["B", 3], ["C", 1], ["C", 2], ["C", 3]] 
multi_product(['A', 'B', 'C'], [1, 2, 3], ['x', 'y', 'z']) 
# => [["A", 1, "x"], ["A", 1, "y"], ["A", 1, "z"], ["A", 2, "x"], ["A", 2, "y"], ["A", 2, "z"], ["A", 3, "x"], ["A", 3, "y"], ["A", 3, "z"], ["B", 1, "x"], ["B", 1, "y"], ["B", 1, "z"], ["B", 2, "x"], ["B", 2, "y"], ["B", 2, "z"], ["B", 3, "x"], ["B", 3, "y"], ["B", 3, "z"], ["C", 1, "x"], ["C", 1, "y"], ["C", 1, "z"], ["C", 2, "x"], ["C", 2, "y"], ["C", 2, "z"], ["C", 3, "x"], ["C", 3, "y"], ["C", 3, "z"]] 
multi_product(['A', 'B', 'C'], [1, 2, 3], ['x', 'y', 'z'], [4, 5, 6]) 
# => [["A", 1, "x", 4], ["A", 1, "x", 5], ["A", 1, "x", 6], ["A", 1, "y", 4], ["A", 1, "y", 5], ["A", 1, "y", 6], ["A", 1, "z", 4], ["A", 1, "z", 5], ["A", 1, "z", 6], ["A", 2, "x", 4], ["A", 2, "x", 5], ["A", 2, "x", 6], ["A", 2, "y", 4], ["A", 2, "y", 5], ["A", 2, "y", 6], ["A", 2, "z", 4], ["A", 2, "z", 5], ["A", 2, "z", 6], ["A", 3, "x", 4], ["A", 3, "x", 5], ["A", 3, "x", 6], ["A", 3, "y", 4], ["A", 3, "y", 5], ["A", 3, "y", 6], ["A", 3, "z", 4], ["A", 3, "z", 5], ["A", 3, "z", 6], ["B", 1, "x", 4], ["B", 1, "x", 5], ["B", 1, "x", 6], ["B", 1, "y", 4], ["B", 1, "y", 5], ["B", 1, "y", 6], ["B", 1, "z", 4], ["B", 1, "z", 5], ["B", 1, "z", 6], ["B", 2, "x", 4], ["B", 2, "x", 5], ["B", 2, "x", 6], ["B", 2, "y", 4], ["B", 2, "y", 5], ["B", 2, "y", 6], ["B", 2, "z", 4], ["B", 2, "z", 5], ["B", 2, "z", 6], ["B", 3, "x", 4], ["B", 3, "x", 5], ["B", 3, "x", 6], ["B", 3, "y", 4], ["B", 3, "y", 5], ["B", 3, "y", 6], ["B", 3, "z", 4], ["B", 3, "z", 5], ["B", 3, "z", 6], ["C", 1, "x", 4], ["C", 1, "x", 5], ["C", 1, "x", 6], ["C", 1, "y", 4], ["C", 1, "y", 5], ["C", 1, "y", 6], ["C", 1, "z", 4], ["C", 1, "z", 5], ["C", 1, "z", 6], ["C", 2, "x", 4], ["C", 2, "x", 5], ["C", 2, "x", 6], ["C", 2, "y", 4], ["C", 2, "y", 5], ["C", 2, "y", 6], ["C", 2, "z", 4], ["C", 2, "z", 5], ["C", 2, "z", 6], ["C", 3, "x", 4], ["C", 3, "x", 5], ["C", 3, "x", 6], ["C", 3, "y", 4], ["C", 3, "y", 5], ["C", 3, "y", 6], ["C", 3, "z", 4], ["C", 3, "z", 5], ["C", 3, "z", 6]] 

它所做的是需要一個必要的參數(基地),它響應到product,然後是*args需要可變數量的其他參數並將它們存儲在數組參數中。然後,您可以使用*解構陣列回參數列表,這裏面調用做product(*args),這樣(在第二個例子中)結束看起來像

['A', 'B', 'C'].product([1, 2, 3], ['x', 'y', 'z']) 
+0

謝謝你的回答。我缺少的信息是將'*'放在數組的前面,將它分離爲多個方法參數。 – Okomikeruko