Question

Le mot Let je le tableau suivant:

arr = [[5, 1], [2, 7]]

et je veux trouver l'élément minimal, comparant le second élément des éléments. L'élément minimum sera [5, 1] depuis 1 est inférieure à 7. Je peux utiliser le code suivant:

arr.min {|a,b| a[1] <=> b[1]}

Pour calculer le maximum, je peux faire la même chose:

arr.max {|a,b| a[1] <=> b[1]}

Cela donne [2, 7].

J'utilise le même bloc tout le temps. Je voudrais avoir quelque part que bloc et de fournir à la fonction min / max. J'espérais quelque chose comme:

blo = lambda {|a,b| a[1] <=> b[1]}
arr.min blo

fonctionnerait, mais il n'a pas. Toute idée sur la façon dont je peux le faire?

Était-ce utile?

La solution

Utilisez l'opérateur & pour tourner un objet Proc dans un bloc.

arr.min &blo

Autres conseils

@ La réponse de sepp2k est le plus général, mais dans votre cas spécifique, je voudrais simplement utiliser

arr.min_by(&:last)
arr.max_by(&:last)

puisque c'est beaucoup plus évident que tous les accolades et les crochets et les indices de tableau flottant autour.

Si tout ce que vous avez besoin est minimum et maximum, vous pouvez utiliser la méthode Enumerable#minmax et calculer à la fois à la fois:

min, max = arr.minmax {|a,b| a[1] <=> b[1]}
#=> [[5, 1], [2, 7]]
min
#=> [5, 1]
max
#=> [2, 7]

Edit: Bon sang, je viens de remarquer il y a aussi minmax_by, de sorte que vous pouvez combiner avec la méthode last et avoir:

min, max = arr.minmax_by &:last

que diriez-vous?

=> [[5, 4], [9, 5], [2, 7]]
>> arr.sort!{|x,y| x[1]<=>y[1] }
=> [[5, 4], [9, 5], [2, 7]]
>> min,max=arr[0],arr[-1]
=> [[5, 4], [2, 7]]

Une solution plus générale à des problèmes comme celui-ci est d'éviter les tableaux imbriqués entièrement et utiliser à la place une classe. Vous pouvez ensuite définir l'opérateur pour cette <=> classe, vous donnant accès à toutes les fonctions du mixin Comparable (http://ruby-doc.org/core/classes/Comparable.html) vous donne la <, <= ==> = et> opérateurs et le procédé 'entre?

Ceci est juste un exemple, dans la vie réelle que vous utilisez des classes qui décrivent ce qu'ils stockent:

class Duo

  include Comparable

  def initialize( a, b )
      @a = a
      @b = b
  end

  def <=>(rhs)
      @b <=> rhs.b
  end

end

Si vous avez un tableau de Duo objet que vous pouvez ensuite utiliser les fonctions min, max, et trier sans avoir à définir l'opérateur de comparaison. Alors ...

@a = Duo.new( 1, 10 )
@b = Duo.new( 2, 5 )
@c = Duo.new( 3, 1 )

[ @a, @b, @c ].sort

renverrait le tableau [@c, @b, @a]

[@a, @b, @c].max

renverrait @a

Ceci est bien plus le « Ruby Way » que des structures de données imbriquées avec une logique qui repose sur des positions dans des tableaux. Il prend plus de travail un peu au début, mais vous le trouverez beaucoup mieux à long terme.

Ruby est un objet très langage de programmation orienté et fournit des outils très puissants pour vous d'utiliser. Je recommande vivement la lecture d'un livre comme « The Ruby Langage de programmation » ou « The Way Ruby » pour obtenir une bonne vue d'ensemble de la puissance de la langue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top