2016-07-18 13 views
4
a = [ 'a' ] 
b = [ 'b' ] 

def c 

    return [ 'c' ], [ 'd' ] 

end 

a, b += C# -> would be awesome, but gives syntax error 

a, b = a + c.first, b + c.last # clunky and will call method twice... 

# desired result 
# 
a == [ 'a', 'c' ] 
b == [ 'b', 'd' ] 

Сейчас я часто пишу:Есть ли ruby ​​oneliner для конкатенации вложенных массивов без временных копий?

t, tt = c 
a += t 
b += tt 

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

Редактировать: Одноэлементные массивы, похоже, смутили некоторых людей, поскольку несколько ответов ниже просто не отвечают на вопрос. Я сделал это более ясно, позволяя каждому массиву иметь как минимум 2 элемента.

Редактировать2: Я подал feature request с рубиновым сердечником для реализации сложных назначений на разрушенных массивах.

+1

Пожалуйста, никогда не изменять ответы, которые, как вы это сделали , Не стесняйтесь публиковать свой собственный ответ в случае, который, по вашему мнению, никто не предоставил, соответствует вашим потребностям. – mudasobwa

+0

Хорошо, не стоит беспокоиться, но на самом деле он ответил бы на вопрос с помощью редактирования ... теперь он не отвечает на этот вопрос .... – nus

+1

Это не ваша забота, кроме того, что вы повторно задали вопрос после все представленные ответы были даны. У вас есть в основном три варианта: принять ответ, перевернуть/пропустить его и проигнорировать. Вам не разрешают отвечать на вопросы, даже если вы думаете, что это улучшит их. – mudasobwa

ответ

5
a,b = [a+b,c].transpose 
    #=> [["a", "c"], ["b", "d"]] 
a #=> ["a", "c"] 
b #=> ["b", "d"] 
+1

плюс один для 'транспозиция'. Не знал об этом. –

+0

Это не работает: оно дает 'a = [" a ", [" c "]]', означающее, что оно добавляется вместо конкатенаций. – nus

5
a, b = (a+b).zip(c) 
# a => ["a", "c"] 
# b => ["b", "d"] 

Надеется, что это помогает.

+2

'(a + b) .zip (c)', нет необходимости сглаживать. –

+0

О, это правда ... это еще лучше. Не могли бы вы добавить свой ответ тоже. Или мне следует обновить свой ответ? –

+1

Очень приятно, улучшение по сравнению с тем, что я предложил! –

3

Поскольку было требование «без временных копий,» Я хотел бы опубликовать решение Inplace модификации любого количества массивов

a1 = [ 'a1' ] 
a2 = [ 'a2' ] 
a3 = [ 'a3' ] 
aa = [ a1, a2, a3 ] 
cc = [ 'c1', 'c2', 'c3' ] 

aa.each_with_object(cc.each) { |e, memo| e << memo.next } 
#⇒ #<Enumerator: ["c1", "c2", "c3"]:each> # do not care, it’s memo 

[a1, a2, a3] 
#⇒ [ ["a1", "c1"], ["a2", "c2"], ["a3", "c3"] ] 

ли cc массив по какой-то причине массив массивов , как указано в вопросе, он должен сглаживаться на каком-то шаге, в зависимости от того, как он должен быть добавлен в массивы a.

+0

Это не работает: оно дает 'a = [" a ", [" c "]]', означающее, что оно добавляется вместо конкатенаций. Однако этому мне удалось адаптировать его, чтобы он действительно работал: '[a, b] .each_with_object (c.each) {| e, memo | e.concat memo.next} '. Это по-прежнему довольно неуклюжий и загадочный, поэтому я сомневаюсь, что я буду использовать его для простого метода возврата destructure, но он масштабируется, честная игра. – nus

+1

Это отлично работает для любого, кто умеет читать до конца и сглаживает возвращаемый счетчик: 'aa.each_with_object (cc.each) {| e, memo | e. << (* memo.next)} '. – mudasobwa

0

Ни один из ответов пока не работает, поэтому пока я придумал nest_concat! (Deep_concat казалось некорректным, так как мы хотим один глубокий):

class Array 

    def nest_concat! other 

     each_with_index { |arr, i| self[i].concat other[ i ] } 

    end 

    def nest_concat other 

     d = map(&:dup) 
     each_with_index { |arr, i| d[i].concat other[ i ] } 

     d 

    end 

end 

Позволяет написать:

a = [ 'a', 'b' ] 
b = [ 'c', 'd' ] 

def c 

    return [ 'A', 'B' ], [ 'C', 'D' ] 

end 

[ a, b ].nest_concat! c 
p a 
p b 

дает

["a", "b", "A", "B"] 
["c", "d", "C", "D"] 
+0

То, что оно дает, противоречит разделу «желаемый результат» в вопросе, так как к 13:00 CET. – mudasobwa

+0

Нет, это не так. [Это оригинальный вопрос] (https://stackoverflow.com/revisions/38428151/1), который никогда не менялся, просто обновлялся, чтобы помочь людям не ошибаться в коде. Это оригинальный вопрос с этим решением: https://ideone.com/q8IAA2 – nus

+0

'return ['a'], ['b']' в Ruby возвращает '[['a'], ['b']] ', а не' ['a', 'b'] '. Вы просто неправильно истолковали его, как и все остальные. Вот почему заголовок вопроса заключается в конкатенации вложенных массивов. – nus

 Смежные вопросы

  • Нет связанных вопросов^_^