2009-10-09 13 views
59

Jaki jest sposób Ruby do osiągnięcia następujących celów?Połączenie dwóch tablic w Rubi

a = [1,2] 
b = [3,4] 

Chcę tablicy:

=> [f(1,3) ,f(1,4) , f(2,3) ,f(2,4)] 
+0

To byłaby poprawna odpowiedź teraz http://stackoverflow.com/a/12011316/135767, mimo że http://stackoverflow.com/questions/12011294/combining-two-arrays-to-create-a-two -dimensional-array-in-ruby jest duplikatem tego pytania. – lucasarruda

Odpowiedz

116

Można użyć product aby iloczyn kartezjański tablic, potem zbierać wyniki funkcyjnych.

a.product(b) => [[1, 3], [1, 4], [2, 3], [2, 4]] 

Więc można użyć map lub collect aby uzyskać wyniki. Są to różne nazwy dla tej samej metody.

a.product(b).collect { |x, y| f(x, y) } 
+0

Produkt jest wbudowany tylko od 1.9. – Pesto

+7

Produkt jest w wersji 1.8.7 - Używam go do zrobienia dokładnie tego, o co prosi Pierr. –

+1

@FloatingRock, które jest niepoprawne, a połączenie nie jest permuacją. Zobacz http://www.ruby-doc.org/core-2.1.3/Array.html#method-i-product –

8
a.map {|x| b.map {|y| f(x,y) } }.flatten 

UWAGA: W 1.8.7+ można dodać 1 jako argument do spłaszczenia, więc można jeszcze uzyskać poprawne wyniki, gdy f powraca tablica.

Oto abstrakcją dla dowolnej liczby tablic:

def combine_arrays(*arrays) 
    if arrays.empty? 
    yield 
    else 
    first, *rest = arrays 
    first.map do |x| 
     combine_arrays(*rest) {|*args| yield x, *args } 
    end.flatten 
     #.flatten(1) 
    end 
end 

combine_arrays([1,2,3],[3,4,5],[6,7,8]) do |x,y,z| x+y+z end 
# => [10, 11, 12, 11, 12, 13, 12, 13, 14, 11, 12, 13, 12, 13, 14, 13, 14, 15, 12, 13, 14, 13, 14, 15, 14, 15, 16] 
+0

To zadziała, chociaż nie jestem pewien, czy jest to najlepszy sposób (choć nie mogę wymyślić lepszego, więc +1) –

+0

Chciałbym móc +2 dla kombinacji arbitralnej ilości tablic. Bardzo fajny! – pierrotlefou

+0

też się z tym zetknąłem ... ale wtedy wiedziałem, że tam powinien być łatwiejszy sposób na zrobienie tego ... +1 za to, ale @Aaron Hinni odpowie na jego czystsze – Orlando

4

Facets ma Array#product który daje iloczynu macierzy. Jest również aliasowany jako ** operator dla przypadku dwóch tablic. Korzystanie że to będzie wyglądać następująco:

require 'facets/array' 
a = [1,2] 
b = [3,4] 

(a.product b).collect {|x, y| f(x, y)} 

Jeśli używasz Ruby 1.9, product jest wbudowana funkcja Array.

+0

Dlaczego ludzie ciągle powtarzają, że produkt Array # to 1.9izm? Jest przynajmniej w wersji 1.8.7. –

+3

http://apidock.com/ruby/Array/product: był w 1.8.7-p72. –

Powiązane problemy