Слияние и чередование двух массивов в Ruby



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



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


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



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


просматривая массив Ruby и перечислимые документы, я не вижу такого метода, который выполнит это.



есть ли способ сделать это без итерации через каждый массив?

512   9  

9 ответов:

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

a.zip(s).flatten.compact

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

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

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

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

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

new_array = a | s
s.inject(a, :<<)

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

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

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

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"]

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

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

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

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

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

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

один из способов сделать перемежение, а также гарантировать, какой из них является самым большим массивом для метода 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"]
arr = [0, 1]
arr + [2, 3, 4]

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

Comments

    Ничего не найдено.