Слияние и чередование двух массивов в Ruby - PullRequest
101 голосов
/ 06 сентября 2011

У меня есть следующий код:

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

Я хочу объединить массив s в массив a, что даст мне:

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

Просмотр рубинаArray и Enumerable docs, я не вижу такого метода, который бы этого достиг.

Есть ли способ, которым я могу сделать это без перебора каждого массива?

Ответы [ 9 ]

167 голосов
/ 06 сентября 2011

Вы можете сделать это с:

a.zip(s).flatten.compact
32 голосов
/ 06 сентября 2011

Это не даст массив результатов в том порядке, в котором попросил Крис, но если порядок результирующего массива не имеет значения, вы можете просто использовать a |= b.Если вы не хотите изменять a, вы можете написать a | b и присвоить результат переменной.

См. Документацию по объединению для класса Array по адресу http://www.ruby -doc..org / core / classes / Array.html # M000275 .

В этом ответе предполагается, что вам не нужны дублирующие элементы массива.Если вы хотите разрешить дублирование элементов в вашем окончательном массиве, a += b должен сделать свое дело.Опять же, если вы не хотите изменять a, используйте a + b и присвойте результат переменной.

В ответ на некоторые комментарии на этой странице эти два решения будут работать с массивамилюбого размера.

28 голосов
/ 05 декабря 2014

Если вы не хотите дублировать, почему бы просто не использовать оператор union :

new_array = a | s
6 голосов
/ 08 февраля 2014

Вот решение, которое позволяет чередовать несколько массивов разных размеров (общее решение):

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"]
6 голосов
/ 05 сентября 2012
s.inject(a, :<<)

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

Это не дает вам заказ, который вы просили, но это хороший способ объединения двух массивов путем добавления к одному.

5 голосов
/ 06 сентября 2011

Это не совсем элегантно, но работает для массивов любого размера:

>> a.map.with_index { |x, i| [x, i == a.size - 2 ? s.last : s.first] }.flatten[0..-2] 
#=> ["Cat", "and", "Dog", "&", "Mouse"]
3 голосов
/ 03 мая 2014

Как насчет более общего решения, которое работает, даже если первый массив не самый длинный и принимает любое количество массивов?

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

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

 => ["Cat", "and", "Dog", "&", "Mouse"]
1 голос
/ 05 февраля 2018

Один из способов выполнить чередование, а также гарантировать, какой массив является самым большим для метода zip, - это заполнить один из массивов nil до другого размера массива. Таким образом, вы также гарантируете, какой элемент какого массива будет на первой позиции:

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"]
0 голосов
/ 13 сентября 2012
arr = [0, 1]
arr + [2, 3, 4]

//outputs [0, 1, 2, 3, 4]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...