2015-08-05 3 views
4

Допустим, у меня есть массивZip массив массивов в другой массив

arr1 = ["a", "b", "c"] 

, и я хочу, чтобы пронестись массив массивов к нему

arr2 = [[1, "foo"], [2, "bar"], [3, "baz"]] 

так, что конечный результат

[["a", 1, "foo"], ["b", 2, "bar"], ["c", 3, "baz"]] 

Прямо сейчас, что я делаю, arr1.zip(arr2).map!(&:flatten), но мне интересно, есть ли лучший способ сделать это?

+0

Первое, что приходит на ум, это 'each_index 'итерация, затем« вставляем »элемент из arr1 в элемент arr2. Если вы сочтете это полезным, я опубликую, но он кажется длиннее, чем у вас сейчас. – onebree

+0

Я не вижу, что случилось с тем, как вы это делаете, но альтернативой может быть «arr2.each_with_index {| a, i | a.unshift (arr1 [i])} '... но на самом деле, ваш лучше. – SteveTurczyn

ответ

10

Другой способ:

arr1.zip(*arr2.transpose) 
# => [["a", 1, "foo"], ["b", 2, "bar"], ["c", 3, "baz"]] 
+0

Это умное использование транспонирования. –

+1

Это не сработает, если 'arr2' содержит массивы разных размеров, не является симметричным, не работает, если оба содержат массивы массивов и решение OP все еще яснее, но я должен признать, что это довольно умно. – ndn

+0

Ницца, D, но @ndn имеет точку .. –

1
arr2.each_with_index{ |el,i| el.unshift(arr1[i]) } 

Возможно, вам это нравится?

+1

Если вы делаете unshift, вы мутируете объект, поэтому вам не нужен бит 'map! '. Исходный массив будет меняться независимо. – SteveTurczyn

+0

@SteveTurczyn хорошая точка, обновлено. Хотя ответ Догити намного лучше. –

3

Вот два других (тесно связанных с ними) способами:

enum = arr1.to_enum 
arr2.map { |a| [enum.next].concat(a) } 
    #=> [["a", 1, "foo"], ["b", 2, "bar"], ["c", 3, "baz"]] 

или

arr1_cpy = arr1.dup 
arr2.map { |a| [arr1_cpy.shift].concat(a) } 
    #=> [["a", 1, "foo"], ["b", 2, "bar"], ["c", 3, "baz"]] 
Смежные вопросы