/ / Scal i przeplataj dwie tablice w Ruby - ruby, tablice

Scal i przeplataj dwie tablice w Ruby - ruby, tablice

Mam następujący kod:

a = ["Cat", "Dog", "Mouse"]
s = ["and", "&"]

Chcę scalić tablicę s do tablicy a co dałoby mi:

["Cat", "and", "Dog", "&", "Mouse"]

Przeglądając Ruby Array i Enumerable docs, nie widzę takiej metody, która by to osiągnęła.

Czy istnieje sposób, w jaki mogę to zrobić bez iteracji po każdej tablicy?

Odpowiedzi:

163 dla odpowiedzi nr 1

Możesz to zrobić za pomocą:

a.zip(s).flatten.compact

33 dla odpowiedzi nr 2

To nie da tablicy wyników w kolejności, o którą prosił Chris, ale jeśli kolejność wynikowej tablicy nie ma znaczenia, możesz po prostu użyć a |= b. Jeśli nie chcesz mutować a, Możesz pisać a | b i przypisz wynik do zmiennej.

Zobacz dokumentację set union dla klasy Array pod adresem http://www.ruby-doc.org/core/classes/Array.html#M000275.

Ta odpowiedź zakłada, że ​​nie chcesz zduplikowanych elementów tablicy. Jeśli chcesz zezwolić na zduplikowane elementy w ostatecznej tablicy, a += b powinien załatwić sprawę. Ponownie, jeśli nie chcesz mutować a, posługiwać się a + b i przypisz wynik do zmiennej.

W odpowiedzi na niektóre komentarze na tej stronie, te dwa rozwiązania będą działać z tablicami o dowolnym rozmiarze.


29 dla odpowiedzi nr 3

Jeśli nie chcesz duplikatu, dlaczego nie użyć po prostu rozszerzenia unia operator:

new_array = a | s

7 dla odpowiedzi № 4
s.inject(a, :<<)

s   #=> ["and", "&"]
a   #=> ["Cat", "Dog", "Mouse", "and", "&"]

Nie daje takiej kolejności, o jaką prosiłeś, ale jest to dobry sposób na scalenie dwóch tablic przez dołączenie do jednej.


6 dla odpowiedzi № 5

Oto rozwiązanie, które umożliwia przeplatanie wielu tablic o różnych rozmiarach (rozwiązanie ogólne):

arr = [["Cat", "Dog", "Mouse", "boo", "zoo"],
["and", "&"],
["hello", "there", "you"]]

first, *rest = *arr; first.zip(*rest).flatten.compact
=> ["Cat", "and", "hello", "Dog", "&", "there", "Mouse", "you", "boo", "zoo"]

5 dla odpowiedzi № 6

Nie jest to zbyt eleganckie, ale działa w przypadku tablic o dowolnym rozmiarze:

>> a.map.with_index { |x, i| [x, i == a.size - 2 ? s.last : s.first] }.flatten[0..-2]
#=> ["Cat", "and", "Dog", "&", "Mouse"]

2 dla odpowiedzi № 7

Co powiesz na bardziej ogólne rozwiązanie, które działa nawet wtedy, gdy pierwsza tablica nie jest najdłuższa i akceptuje dowolną liczbę tablic?

a = [
["and", "&"],
["Cat", "Dog", "Mouse"]
]

b = a.max_by(&:length)
a -= [b]
b.zip(*a).flatten.compact

=> ["Cat", "and", "Dog", "&", "Mouse"]

0 dla odpowiedzi № 8

Jednym ze sposobów wykonania przeplotu, a także zagwarantowania, która z nich jest największą tablicą dla metody zip, jest wypełnienie jednej z tablic nil aż do innego rozmiaru tablicy. W ten sposób gwarantujesz również, który element której tablicy będzie na pierwszej pozycji:

preferred_arr = ["Cat", "Dog", "Mouse"]
other_arr = ["and","&","are","great","friends"]

preferred_arr << nil while preferred_arr.length < other_arr.length
preferred_arr.zip(other_arr).flatten.compact
#=> ["Cat", "and", "Dog", "&", "Mouse", "are", "great", "friends"]

-1 dla odpowiedzi № 9
arr = [0, 1]
arr + [2, 3, 4]

//outputs [0, 1, 2, 3, 4]