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 1Moż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]