J'ai besoin d'un moyen de diviser un tableau en un groupe de tableaux dans un autre tableau de taille égale. Quelqu'un a-t-il une méthode pour le faire?
Par exemple
a = [0, 1, 2, 3, 4, 5, 6, 7]
a.method_i_need(3)
a.inspect
=> [[0,1,2], [3,4,5], [6,7]]
Vous cherchez Enumerable#each_slice
a = [0, 1, 2, 3, 4, 5, 6, 7]
a.each_slice(3) # => #<Enumerator: [0, 1, 2, 3, 4, 5, 6, 7]:each_slice(3)>
a.each_slice(3).to_a # => [[0, 1, 2], [3, 4, 5], [6, 7]]
Peut-être que je lis mal la question car l'autre réponse est déjà acceptée, mais il semblait que vous vouliez diviser le tableau en 3 groupes égaux, quelle que soit la taille de chaque groupe, plutôt que de le diviser en N groupes de 3 comme les réponses précédentes le font. Si c'est ce que vous recherchez, Rails (ActiveSupport) a également une méthode appelée in_groups :
a = [0,1,2,3,4,5,6]
a.in_groups(2) # => [[0,1,2,3],[4,5,6,nil]]
a.in_groups(3, false) # => [[0,1,2],[3,4], [5,6]]
Je ne pense pas qu'il existe un équivalent Ruby, cependant, vous pouvez obtenir à peu près les mêmes résultats en ajoutant cette méthode simple:
class Array; def in_groups(num_groups)
return [] if num_groups == 0
slice_size = (self.size/Float(num_groups)).ceil
groups = self.each_slice(slice_size).to_a
end; end
a.in_groups(3) # => [[0,1,2], [3,4,5], [6]]
La seule différence (comme vous pouvez le voir) est que cela ne répartira pas "l'espace vide" dans tous les groupes; chaque groupe mais le dernier est de taille égale, et le dernier groupe contient toujours le reste plus tout "l'espace vide".
Mise à jour: Comme @rimsky l'a astucieusement souligné, la méthode ci-dessus ne donnera pas toujours le bon nombre de groupes (parfois elle créera plusieurs "groupes vides" à la fin, et laissez-les de côté). Voici une version mise à jour, épurée de définition d'ActiveSupport qui répartit les extras pour remplir le nombre de groupes demandé.
def in_groups(number)
group_size = size / number
leftovers = size % number
groups = []
start = 0
number.times do |index|
length = group_size + (leftovers > 0 && leftovers > index ? 1 : 0)
groups << slice(start, length)
start += length
end
groups
end
Essayer
a.in_groups_of(3,false)
Il fera votre travail
Comme l'a écrit mltsy, in_groups(n, false)
devrait faire le travail.
Je voulais juste ajouter une petite astuce pour obtenir le bon équilibre my_array.in_group(my_array.size.quo(max_size).ceil, false)
.
Voici un exemple pour illustrer cette astuce:
a = (0..8).to_a
a.in_groups(4, false) => [[0, 1, 2], [3, 4], [5, 6], [7, 8]]
a.in_groups(a.size.quo(4).ceil, false) => [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
Cela nécessite une meilleure intelligence pour étaler les pièces supplémentaires, mais c'est un début raisonnable.
def i_need(bits, r)
c = r.count
(1..bits - 1).map { |i| r.shift((c + i) * 1.0 / bits ) } + [r]
end
> i_need(2, [1, 3, 5, 7, 2, 4, 6, 8])
=> [[1, 3, 5, 7], [2, 4, 6, 8]]
> i_need(3, [1, 3, 5, 7, 2, 4, 6, 8])
=> [[1, 3, 5], [7, 2, 4], [6, 8]]
> i_need(5, [1, 3, 5, 7, 2, 4, 6, 8])
=> [[1, 3], [5, 7], [2, 4], [6], [8]]