Ответ 1
Вы можете сделать это с помощью
a.zip(s).flatten.compact
У меня есть следующий код:
a = ["Cat", "Dog", "Mouse"]
s = ["and", "&"]
Я хочу объединить массив s
в массив a
, который дал бы мне:
["Cat", "and", "Dog", "&", "Mouse"]
Просматривая Ruby Array и Enumerable docs, я не вижу такого метода, который выполнит это.
Есть ли способ, которым я могу это сделать без итерации через каждый массив?
Вы можете сделать это с помощью
a.zip(s).flatten.compact
Это не даст массив результатов в порядке, на который попросил Крис, но если порядок полученного массива не имеет значения, вы можете просто использовать a |= b
. Если вы не хотите мутировать a
, вы можете написать a | b
и присвоить результат переменной.
См. документацию объединения соединений для класса Array в http://www.ruby-doc.org/core/classes/Array.html#M000275.
В этом ответе предполагается, что вы не хотите дублировать элементы массива. Если вы хотите разрешить дублирование элементов в вашем конечном массиве, a += b
должен сделать трюк. Опять же, если вы не хотите мутировать a
, используйте a + b
и присвойте результат переменной.
В ответ на некоторые комментарии на этой странице эти два решения будут работать с массивами любого размера.
Если вы не хотите дублировать, почему бы просто не использовать оператор union:
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"]
Чтобы справиться с ситуацией, когда оба a
& s
не одного размера:
a.zip(s).flatten.compact | s
.compact
удалит nil
, когда a
больше, чем s
| s
добавит оставшиеся элементы из s
, когда a
меньше, чем s
arr = [0, 1]
arr + [2, 3, 4]
//outputs [0, 1, 2, 3, 4]