somearray = ["some", "thing"]
anotherarray = ["another", "thing"]
somearray.Push(anotherarray.flatten!)
J'esperais
["some","thing","another","thing"]
Vous avez une idée réalisable, mais le #flatten!
est au mauvais endroit - il aplatit son récepteur, vous pouvez donc l'utiliser pour transformer [1, 2, ['foo', 'bar']]
en [1,2,'foo','bar']
.
J'oublie sans doute quelques approches, mais vous pouvez concaténer:
a1.concat a2
a1 + a2 # creates a new array, as does a1 += a2
ou prepend/append:
a1.Push(*a2) # note the asterisk
a2.unshift(*a1) # note the asterisk, and that a2 is the receiver
ou épissure:
a1[a1.length, 0] = a2
a1[a1.length..0] = a2
a1.insert(a1.length, *a2)
ou ajouter et aplatir:
(a1 << a2).flatten! # a call to #flatten instead would return a new array
Vous pouvez simplement utiliser l'opérateur +
!
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]
Vous pouvez lire tout sur la classe array ici: http://Ruby-doc.org/core/classes/Array.html
La méthode la plus propre consiste à utiliser la méthode Array # concat ; il ne créera pas de nouveau tableau (contrairement à Array # + qui fera la même chose mais créera un nouveau tableau).
Directement à partir de la documentation ( http://www.Ruby-doc.org/core-1.9.3/Array.html#method-i-concat ):
concat (other_ary)
Ajoute les éléments de other_ary à soi-même.
Alors
[1,2].concat([3,4]) #=> [1,2,3,4]
Le tableau # concat n'écrasera pas un tableau multidimensionnel s'il est passé en argument. Vous devrez gérer cela séparément:
arr= [3,[4,5]]
arr= arr.flatten #=> [3,4,5]
[1,2].concat(arr) #=> [1,2,3,4,5]
Enfin, vous pouvez utiliser notre gem corelib ( https://github.com/corlewsolutions/corelib ) qui ajoute des aides utiles aux classes de base Ruby. En particulier, nous avons une méthode Array # add_all qui aplatira automatiquement les tableaux multidimensionnels avant d'exécuter le concat.
Méthode simple fonctionnant avec Ruby version> = 2.0 mais pas avec les versions antérieures:
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]
Essayez ceci, il va combiner vos tableaux pour supprimer les doublons
array1 = ["foo", "bar"]
array2 = ["foo1", "bar1"]
array3 = array1|array2
http://www.Ruby-doc.org/core/classes/Array.html
Documentation complémentaire sur "Set Union"
Voici deux manières, notez dans ce cas que la première façon assigne un nouveau tableau (se traduit par 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"]
(array1 + array2).uniq
De cette façon, vous obtenez les éléments de array1 en premier. Vous n'obtiendrez aucun doublon.
a = ["some", "thing"]
b = ["another", "thing"]
Pour ajouter b
à a
et stocker le résultat dans a
:
a.Push(*b)
ou
a += b
Dans les deux cas, a
devient:
["some", "thing", "another", "thing"]
mais dans le premier cas, les éléments de b
sont ajoutés au tableau a
existant, et dans le dernier cas, les deux tableaux sont concaténés et le résultat est stocké dans a
.
En développant la réponse de @ Pilcrow, la seule réponse appropriée pour les tableaux de grande taille est concat
(+
) car elle est rapide et n'alloue pas un nouvel objet à récupérer lors de son fonctionnement dans une boucle.
Voici le repère:
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
Résultats:
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 <main>': stack level too deep (SystemStackError)
Comme vous pouvez le voir avec Push
jette un ERREUR: stack level too deep (SystemStackError)
lorsque les tableaux sont suffisamment grands.
La question essentielle consiste à savoir "comment concaténer des tableaux en Ruby". Naturellement, la solution consiste à utiliser concat
ou +
comme indiqué dans presque toutes les réponses.
Une extension naturelle de la question serait "comment effectuer une concaténation par rangée de tableaux 2D en Ruby". Lorsque j'ai cherché "Matrices de concaténation" dans Google, cette question SO était le meilleur résultat. J'ai donc pensé laisser ma réponse à cette question (non demandée mais liée) ici pour la postérité.
Dans certaines applications, vous pouvez vouloir "concaténer" deux tableaux 2D par rangée. Quelque chose comme,
[[a, b], | [[x], [[a, b, x],
[c, d]] | [y]] => [c, d, y]]
C'est quelque chose comme "augmenter" une matrice. Par exemple, j'ai utilisé cette technique pour créer une seule matrice d'adjacence afin de représenter un graphique à partir d'un groupe de matrices plus petites. Sans cette technique, j'aurais dû parcourir les composants d'une manière qui aurait pu être source d'erreurs ou frustrante. J'aurais peut-être dû faire un each_with_index
, par exemple. Au lieu de cela, j'ai combiné Zip et aplatir comme suit,
# 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]]
Juste une autre façon de le faire.
[somearray, anotherarray].flatten
=> ["some", "thing", "another", "thing"]
["some", "thing"] + ["another" + "thing"]
Si les nouvelles données peuvent être un tableau ou un scalaire et que vous souhaitez empêcher l'imbrication des nouvelles données s'il s'agissait d'un tableau, l'opérateur Splat est génial! Il retourne un scalaire pour un scalaire et une liste non compressée d'arguments pour un tableau.
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
Je suis surpris que personne n'ait mentionné reduce
, ce qui fonctionne bien lorsque vous avez un tableau de tableaux:
lists = [["a", "b"], ["c", "d"]]
flatlist = lists.reduce(:+) # ["a", "b", "c", "d"]
a = ['a', 'b']
b = ['c', 'd']
arr = [a, b].flatten
Cela ne supprimera pas les bêtises, mais
a|b
enlève les dups.
Je trouve plus facile de pousser ou d’ajouter des tableaux, puis de les aplatir, comme ceci:
somearray = ["some", "thing"]
anotherarray = ["another", "thing"]
somearray.Push anotherarray # => ["some", "thing", ["another", "thing"]]
#or
somearray << anotherarray # => ["some", "thing", ["another", "thing"]]
somearray.flatten! # => ["some", "thing", "another", "thing"]
somearray # => ["some", "thing", "another", "thing"]