2010-04-06 4 views

Répondre

3

Cela devrait faire le travail au cours des dernières versions Ruby:

a.length.downto(1).map{|i| a.combination(i).map{|sub| sub.inject(&:&)}} 
#=> [[[]], [[], [3, 4], [2], [1]], [[3, 4], [2], [2, 3, 4], [1], [1, 3, 4], [1, 2]], [[2, 3, 4], [1, 3, 4], [1, 2], [1, 2, 3, 4]]] 

Here's une question connexe avec une solution similaire. Le "truc" est dans la méthode Array#&, qui calcule l'intersection (comme une opération ensemble) des deux tableaux. C'est associative opération, donc nous pouvons l'appliquer sur chaque sous-tableau à tour de rôle, en gardant le résultat accumulé, par conséquent inject est parfait pour cela. En bref, array.inject(&:&) se traduira par un plus grand sous-ensemble commun d'éléments dans chaque membre de array. &:& est juste un raccourci Ruby pour faire une Proc de méthode nommée & et de le soumettre comme un bloc à inject, au lieu d'écrire:

array.inject{|a,e| a & e} 
+1

@Mladen, Jablonović, c'est une solution élégante impressionante. Pouvez-vous mettre à jour votre réponse pour en expliquer un peu plus comment cela fonctionne? Plus précisément, qu'est-ce que '&: &' et comment cela fonctionne-t-il avec 'Enumerable # inject'? –

Questions connexes