Fusionner et entrelacer deux tableaux dans Ruby

J’ai le code suivant:

a = ["Cat", "Dog", "Mouse"] s = ["and", "&"] 

Je veux fusionner le tableau s en tableau a ce qui me donnerait:

 ["Cat", "and", "Dog", "&", "Mouse"] 

En parcourant les documents Ruby Array et Enumerable, je ne vois pas une telle méthode pour y parvenir.

Y a-t-il un moyen de le faire sans itérer dans 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 a | b et assigne le résultat à une variable.

Reportez-vous à la documentation set 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 d’éléments de tableau en double. Si vous voulez 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 affectez 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 l’opérateur d’ union :

 new_array = a | s 
 s.inject(a, :<<) s #=> ["and", "&"] a #=> ["Cat", "Dog", "Mouse", "and", "&"] 

Cela ne vous donne pas l’ordre que vous avez demandé, mais c’est un bon moyen de fusionner deux tableaux en ajoutant à celui-ci.

Voici une solution qui permet d’entrelacer plusieurs tableaux 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"] 

Ce n’est pas exactement élégant, mais cela fonctionne pour les baies 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"] 

Que diriez-vous d’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 quel est le plus grand tableau pour la méthode zip consiste à remplir un des tableaux jusqu’à la taille de l’autre tableau. De cette façon, vous garantissez également quel élément du 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"] 
 arr = [0, 1] arr + [2, 3, 4] //outputs [0, 1, 2, 3, 4]