Как в Ruby добавить массив к другому массиву и не получить в итоге многомерный результат?

somearray = ["some", "thing"]

anotherarray = ["another", "thing"]

somearray.push(anotherarray.flatten!)

Я ожидал

["some","thing","another","thing"]
Комментарии к вопросу (6)

Вы've получили работоспособную идею, но #расплющить! в неправильном месте -- его плющит его приемник, так что вы можете использовать его, чтобы включить[1, 2, ['фу', 'бар']] " в " [1,2,'фу','бар'].

Я'м, несомненно, забывая некоторые подходы, но вы можете объединения:

a1.concat a2
a1 + a2              # creates a new array, as does a1 += a2

или prepend/конечная:

a1.push(*a2)         # note the asterisk
a2.unshift(*a1)      # note the asterisk, and that a2 is the receiver

или соединение:

a1[a1.length, 0] = a2
a1[a1.length..0] = a2
a1.insert(a1.length, *a2)

или добавить и плющить:


(a1 
Комментарии (14)

Вы можете просто использовать оператор +!

irb(main):001:0> a = [1,2]
=> [1, 2]
irb(main):002:0> b = [3,4]
=> [3, 4]
irb(main):003:0> a + b
=> [1, 2, 3, 4]

Вы можете прочитать все о классе массивов здесь: http://ruby-doc.org/core/classes/Array.html

Комментарии (7)

Самый чистый подход заключается в использовании выбора#функция concat метод; он не будет создавать новый массив (в отличие от массива#+ которая будет делать то же самое, но создать новый массив).

Прямо из документов (http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-concat):

функция concat(other_ary)

добавляет элементы other_ary самостоятельно.

Так

[1,2].concat([3,4])  #=> [1,2,3,4]  

Массив#функция concat не разогнуть многомерный массив, если он передается в качестве аргумента. Вы'll необходимо обрабатывать отдельно:

arr= [3,[4,5]]
arr= arr.flatten   #=> [3,4,5]
[1,2].concat(arr)  #=> [1,2,3,4,5]

Наконец, вы можете использовать наши corelib камень (https://github.com/corlewsolutions/corelib), которые добавляет полезные помощники для рубинового базовые классы. В частности, у нас есть выбора#add_all метод, который автоматически выровнять многомерные массивы перед выполнением метода concat.

Комментарии (2)

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

array1 = ["foo", "bar"]
array2 = ["foo1", "bar1"]

array3 = array1|array2

http://www.ruby-doc.org/core/classes/Array.html

Дополнительную документацию смотрите в разделе "Установить союз"

Комментарии (2)

Простой метод, который работает с версии Ruby >= 2.0, но не с более старыми версиями :

irb(main):001:0> a=[1,2]
=> [1, 2]
irb(main):003:0> b=[3,4]
=> [3, 4]
irb(main):002:0> c=[5,6]
=> [5, 6]
irb(main):004:0> [*a,*b,*c]
=> [1, 2, 3, 4, 5, 6]
Комментарии (5)

Вот два способа, заметьте, в этом случае, что первый способ назначает новый массив ( переводится somearray = somearray + anotherarray )

somearray = ["some", "thing"]

anotherarray = ["another", "thing"]

somearray += anotherarray # => ["some", "thing", "another", "thing"]

somearray = ["some", "thing"]
somearray.concat anotherarray # => ["some", "thing", "another", "thing"]
Комментарии (0)

(массив1 + массив2).уник

Таким образом, вы получите первый массив1 элементов. Вы не получите дубликаты.

Комментарии (0)
a = ["some", "thing"]
b = ["another", "thing"]

Чтобы добавить B до A и сохранить результат в "а":

a.push(*b)

или

a += b

В любом случае, " а " становится:

["some", "thing", "another", "thing"]

но в первом случае, элементы " б "добавляются к уже существующим" а "- массив, и в последнем случае два массива объединяются вместе, и результат сохраняется в "а".

Комментарии (1)

Конкретизируя @абзаца'ы ответить на единственный подходящий ответ для огромных массивов функция concat (+) так быстро и не выделяет новый объект для сборки мусора при работе внутри цикла.

Здесь'с эталоном:

require 'benchmark'

huge_ary_1 = Array.new(1_000_000) { rand(5_000_000..30_000_00) }

huge_ary_2 = Array.new(1_000_000) { rand(35_000_000..55_000_00) }

Benchmark.bm do |bm|
  p '-------------------CONCAT ----------------'
  bm.report { huge_ary_1.concat(huge_ary_2) }

  p '------------------- PUSH ----------------'
  bm.report { huge_ary_1.push(*huge_ary_2)  }
end

Результаты:

       user     system      total        real
"-------------------CONCAT ----------------"
  0.000000   0.000000   0.000000 (  0.009388)
"------------------- PUSH ----------------"
  example/array_concat_vs_push.rb:13:in `block (2 levels) in ': stack level too deep (SystemStackError)

Как вы можете видеть, используя "толчок" бросает ошибка: уровне стека слишком глубоко (SystemStackError), когда массивы достаточно большие.

Комментарии (0)

Просто другой способ сделать это.

[somearray, anotherarray].flatten
=> ["some", "thing", "another", "thing"]
Комментарии (0)

Вопрос, по сути, является "Как объединить массивы в Ruby и". Естественно, ответ должен использовать функция concat или+, как упоминалось почти в каждом ответе.

Естественным продолжением будет вопрос "Как выполнять построчный конкатенации 2Д массивы в Ruby и". Когда я гуглил на "Рубин объединить Матрицы" и этот вопрос был главным результат, поэтому я думал, я хотел бы оставить мой ответ на этот вопрос (невысказанный, но связанные) вопрос здесь для потомков.


В некоторых случаях вы, возможно, захотите, чтобы "объединить" и два 2D массивы строк-мудрый. Что-то вроде:

[[a, b], | [[x],    [[a, b, x],
 [c, d]] |  [y]] =>  [c, d, y]]

Это нечто похожее на "увеличения" а матрица. Например, я использовал эту технику, чтобы создать единую матрицу смежности для представления графа из множества более мелких матриц. Без этой техники мне пришлось бы перебирать компоненты, которые могут быть подвержены ошибкам или неприятно думать об этом. Я мог бы сделать each_with_index, например. Вместо этого я объединил молния и выровнять следующим образом:

# given two multi-dimensional arrays that you want to concatenate row-wise
m1 = [[:a, :b], [:c, :d]]
m2 = [[:x], [:y]]

m1m2 = m1.zip(m2).map(&:flatten)
# => [[:a, :b, :x], [:c, :d, :y]]
Комментарии (0)

Если новые данные могут быть массив или скаляр, и вы хотите предотвратить новые данные, чтобы быть вложенными, если бы это был массив, оператор восклицательный знак-это круто! Он возвращает скаляр на скаляр, и распакованный список аргументов для массива.

в

1.9.3-p551 :020 > a = [1, 2]
 => [1, 2] 
1.9.3-p551 :021 > b = [3, 4]
 => [3, 4] 
1.9.3-p551 :022 > c = 5
 => 5 
1.9.3-p551 :023 > a.object_id
 => 6617020 
1.9.3-p551 :024 > a.push *b
 => [1, 2, 3, 4] 
1.9.3-p551 :025 > a.object_id
 => 6617020 
1.9.3-p551 :026 > a.push *c
 => [1, 2, 3, 4, 5] 
1.9.3-p551 :027 > a.object_id
 => 6617020 

в

Комментарии (0)

["некая", "вещь"] + ["другая" + "вещь"].

Комментарии (1)

Я'м удивлен, никто не упомянул уменьшить, который хорошо работает, когда у вас есть массив массивов:

lists = [["a", "b"], ["c", "d"]]
flatlist = lists.reduce(:+)  # ["a", "b", "c", "d"]
Комментарии (0)
a = ['a', 'b']
b = ['c', 'd']
arr = [a, b].flatten

Это выиграл'т удалить дублированные файлы, но

a|b

удаляет дублированные файлы.

Комментарии (1)

Мне легче толкать или добавить массивов, а затем расплющить их на место, вот так:

somearray = ["some", "thing"]
anotherarray = ["another", "thing"]
somearray.push anotherarray # => ["some", "thing", ["another", "thing"]]
#or
somearray  ["some", "thing", ["another", "thing"]]
somearray.flatten!  # => ["some", "thing", "another", "thing"]
somearray # => ["some", "thing", "another", "thing"]
Комментарии (0)

somearray = [с"какая-то", то "вещь" и]

anotherarray = ["и еще один", то "вещь" и]

somearray + anotherarray

Комментарии (0)