somearray = ["some", "thing"]
anotherarray = ["another", "thing"]
somearray.push(anotherarray.flatten!)
Я ожидал
["some","thing","another","thing"]
ruby
arrays
multidimensional-array
ncvncvn
источник
источник
ri Array@flatten!
Почему этот вопрос набирает столько голосов? Документ явныйArray#flatten!
Сглаживает себя на месте. Возвращает nil, если не было внесено никаких изменений (т.flatten!
что так не работает. Наконец, вопрос отражает логическую проблему, а не проблему оптимизации. Смотрите ответ Пилкроу ниже для получения дополнительной информации.Ответы:
У вас есть подходящая идея, но она
#flatten!
находится не в том месте - она выравнивает приемник, поэтому вы можете использовать ее для превращения[1, 2, ['foo', 'bar']]
в[1,2,'foo','bar']
.Я, несомненно, забыл некоторые подходы, но вы можете объединить :
или добавить / добавить :
или сращивание :
или добавить и выровнять :
источник
Array#concat
не выделяет новый массив, Конкатенация сArray#+
делаетВы можете просто использовать
+
оператор!Вы можете прочитать все о классе массива здесь: http://ruby-doc.org/core/classes/Array.html
источник
a+= b
создает новый массив:c = a = [1,2] ; b = [3,4] ; a += b ; puts c #=> [1,2]
push
метод, описанный @pilcrow.+=
создает новый объект. в таком примере будет возвращен[1, 2].each_with_object([]) { |number, object| object+=number }
пустой массив[]
Самый чистый подход - использовать Array # concat ; он не будет создавать новый массив (в отличие от Array # +, который будет делать то же самое, но создаст новый массив).
Прямо из документов ( http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-concat ):
Так
Массив # concat не сгладит многомерный массив, если он передан в качестве аргумента. Вам нужно будет обработать это отдельно:
Наконец, вы можете использовать наш гем corelib ( https://github.com/corlewsolutions/corelib ), который добавляет полезных помощников в базовые классы Ruby. В частности, у нас есть метод Array # add_all, который автоматически сгладит многомерные массивы перед выполнением concat.
источник
Простой метод, который работает с версией Ruby> = 2.0, но не со старыми версиями:
источник
*
здесь происходит ?[*a, *b]
не работает для более старых версий ruby, т. е. 1.8.7. И хотя Ruby хочет сказать вам, что он из жизни, RHEL6 все еще поддерживается, что делает Ruby 1.8 очень важной целевой версией.[...array1, ...array2]
, просто помня, чтоsplat
оператор в ruby будет*
вместо...
. Это легче запомнитьПопробуйте, это объединит ваши массивы, удалив дубликаты
http://www.ruby-doc.org/core/classes/Array.html
Дальнейшую документацию смотрите на "Set Union"
источник
array1 |= [ "foo1", "bar1" ] #=> [ "foo", "bar", "foo1", "bar1" ]
Вот два способа, обратите внимание, что в этом случае первый способ назначает новый массив (переводится как somearray = somearray + anotherarray)
источник
Для того, чтобы добавить
b
кa
и сохранить результат вa
:или
В любом случае
a
становится:но в первом случае элементы
b
добавляются к существующемуa
массиву, а во втором случае два массива объединяются вместе, и результат сохраняется вa
.источник
a.push(*b)
это не совсем то же самое, чтоa += b
. Первый добавляет новые элементы в существующий массив; последний создает новый массив со всеми элементами и присваивает егоa
. Вы можете увидеть разницу, если вы сделаете что-то вродеaa = a
сохранения ссылки вa
до добавления какого-либо метода, а затем проверки в дальнейшемaa
. В первом случае оно изменяется с новым значениемa
, а во втором оно остается неизменным.(array1 + array2).uniq
Таким образом, вы сначала получаете элементы array1. Вы не получите дубликатов.
источник
При разработке ответа @ Pilcrow единственный подходящий ответ для огромных массивов - это
concat
(+
), поскольку он быстрый и не выделяет новый объект для сбора мусора при работе внутри цикла.Вот эталон:
Результаты:
Как вы можете видеть, использование
push
throws ERROR :stack level too deep (SystemStackError)
когда массивы достаточно велики.источник
По сути, вопрос заключается в том, «как объединить массивы в Ruby». Естественно, ответ заключается в использовании
concat
или+
как упоминалось почти в каждом ответе.Естественным продолжением вопроса будет «как выполнить построчную конкатенацию двумерных массивов в Ruby». Когда я гуглил «матрицы конкатенации рубина», этот SO вопрос был главным результатом, поэтому я решил оставить свой ответ на этот (не заданный, но связанный) вопрос здесь для потомков.
В некоторых приложениях вам может потребоваться «объединить» два 2D-массива по строкам. Что-то вроде,
Это что-то вроде «увеличения» матрицы. Например, я использовал эту технику, чтобы создать одну матрицу смежности для представления графа из множества меньших матриц. Без этой техники мне пришлось бы перебирать компоненты таким образом, чтобы это могло привести к ошибкам или разочарованию. Я мог бы сделать
each_with_index
, например. Вместо этого я объединил zip и flatten следующим образом,источник
Просто еще один способ сделать это.
источник
flatten
выравнивает все как можно рекурсивно. Даже вложенные массивы. Следовательно, еслиsomearray
илиanotherarray
содержит вложенные массивы, они также сглаживаются. Это побочный эффект, который обычно не предназначен.["some", "thing"] + ["another" + "thing"]
источник
[*a] + [*b]
работает"another" + "thing"
это сработает, как ожидалось.Если новые данные могут быть массивом или скаляром, и вы хотите предотвратить вложение новых данных, если это был массив, оператор splat - это круто! Он возвращает скаляр для скаляра и распакованный список аргументов для массива.
источник
Я удивлен, что никто не упомянул
reduce
, что хорошо работает, когда у вас есть массив массивов:источник
Это не удалит дураки, но
удаляет соки
источник
Мне легче вставлять или добавлять массивы, а затем выравнивать их, например, так:
источник
somearray = ["некоторые", "вещь"]
anotherarray = ["другой", "вещь"]
Somearray + Anotherarray
источник