J'ai le code suivant:
a = ["Cat", "Dog", "Mouse"]
s = ["and", "&"]
Je veux fusionner le tableau s
dans le tableau a
qui me donnerait:
["Cat", "and", "Dog", "&", "Mouse"]
En regardant à travers les documents Ruby Array and Enumerable, je ne vois pas de méthode qui y parviendrait.
Est-il possible de le faire sans parcourir chaque tableau?
Vous pouvez le faire avec:
a.Zip(s).flatten.compact
Cela ne donnera pas un tableau de résultats dans l'ordre demandé par Chris, mais si l'ordre du tableau résultant n'a pas d'importance, vous pouvez simplement utiliser a |= b
. Si vous ne voulez pas muter a
, vous pouvez écrire a | b
et assignez le résultat à une variable.
Reportez-vous à la documentation relative à l'union pour la classe Array à l'adresse http://www.Ruby-doc.org/core/classes/Array.html#M000275 .
Cette réponse suppose que vous ne voulez pas que des éléments de tableau en double soient dupliqués. Si vous souhaitez autoriser les éléments en double dans votre tableau final, a += b
devrait faire l'affaire. Encore une fois, si vous ne voulez pas muter a
, utilisez a + b
et assignez le résultat à une variable.
En réponse à certains commentaires sur cette page, ces deux solutions fonctionneront avec des tableaux de toute taille.
Si vous ne voulez pas dupliquer, pourquoi ne pas utiliser simplement l'opérateur nion :
new_array = a | s
Voici une solution qui permet d’entrelacer plusieurs baies de tailles différentes (solution générale):
arr = [["Cat", "Dog", "Mouse", "boo", "Zoo"],
["and", "&"],
["hello", "there", "you"]]
first, *rest = *arr; first.Zip(*rest).flatten.compact
=> ["Cat", "and", "hello", "Dog", "&", "there", "Mouse", "you", "boo", "Zoo"]
s.inject(a, :<<)
s #=> ["and", "&"]
a #=> ["Cat", "Dog", "Mouse", "and", "&"]
Cela ne vous donne pas l'ordre que vous avez demandé, mais c'est une bonne façon de fusionner deux tableaux en ajoutant à celui-ci.
Ce n'est pas vraiment élégant, mais cela fonctionne pour les tableaux de toutes tailles:
>> a.map.with_index { |x, i| [x, i == a.size - 2 ? s.last : s.first] }.flatten[0..-2]
#=> ["Cat", "and", "Dog", "&", "Mouse"]
Pourquoi pas une solution plus générale qui fonctionne même si le premier tableau n’est pas le plus long et accepte un nombre quelconque de tableaux?
a = [
["and", "&"],
["Cat", "Dog", "Mouse"]
]
b = a.max_by(&:length)
a -= [b]
b.Zip(*a).flatten.compact
=> ["Cat", "and", "Dog", "&", "Mouse"]
Une façon de faire l'entrelacement et de garantir celui qui est le plus grand tableau pour la méthode Zip consiste à remplir l'un des tableaux avec nil
jusqu'à la taille de l'autre. De cette façon, vous garantissez également quel élément de quel tableau sera en première position:
preferred_arr = ["Cat", "Dog", "Mouse"]
other_arr = ["and","&","are","great","friends"]
preferred_arr << nil while preferred_arr.length < other_arr.length
preferred_arr.Zip(other_arr).flatten.compact
#=> ["Cat", "and", "Dog", "&", "Mouse", "are", "great", "friends"]
Pour gérer la situation où a
et s
ne sont pas de la même taille:
a.Zip(s).flatten.compact | s
.compact
_ supprime nil
lorsque a
est supérieur à s
| s
ajoutera les éléments restants de s
lorsque a
sera inférieur à s