Frage

Lassen Sie uns sagen, ich habe die folgende Array:

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

und ich möchte das kleinste Element finden, das zweite Element der Elemente zu vergleichen. Das kleinste Element wird [5, 1] da 1 weniger als 7. Ich kann den folgenden Code verwenden:

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

Für die maximale Berechnung kann ich das gleiche tun:

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

Das gibt [2, 7].

Ich verwende den gleichen Block die ganze Zeit. Ich möchte diesen Block irgendwo haben und liefern sie an die Min- / Max-Funktion. Ich hoffte, dass so etwas wie:

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

funktionieren würde, aber es kam nicht. Jede Idee, wie kann ich das tun?

War es hilfreich?

Lösung

Mit dem & Bediener ein Proc Objekt in einen Block zu drehen.

arr.min &blo

Andere Tipps

@ sepp2k Antwort ist das allgemeinere, aber in Ihrem speziellen Fall würde ich nur verwenden

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

denn das ist viel offensichtlicher als all diese geschweiften Klammern und eckige Klammern gesetzt und Array-Indizes im Umlauf.

Wenn alles, was Sie brauchen, Minimum und Maximum, können Sie Enumerable#minmax Methode verwenden und beide berechnen auf einmal:

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

Edit: Verdammt, ich habe gerade bemerkt, gibt es auch minmax_by, so dass Sie es mit last Verfahren kombinieren und haben:

min, max = arr.minmax_by &:last

Wie wäre das?

=> [[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]]

Eine allgemeine Lösung für Probleme wie diese ist verschachtelte Arrays ganz zu vermeiden und eine Klasse stattdessen verwenden. Sie können den Operator <=> für diese Klasse dann definieren Ihnen den Zugriff auf alle Funktionen, die in dem Vergleich mixin geben (http://ruby-doc.org/core/classes/Comparable.html) gibt Ihnen die <, <= , ==,> = und> Betreiber und die Methode 'zwischen?'

Dies ist nur ein Beispiel, im wirklichen Leben würden Sie Klassen verwenden, die beschreiben, was sie speichern:

class Duo

  include Comparable

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

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

end

Wenn Sie ein Array von Duo haben Objekt, das Sie dann die Minimal-, Maximal- verwenden können und Sortierfunktionen, ohne den Vergleichsoperator definieren zu müssen. So ...

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

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

würde das Array zurück [@c, @b, @a]

Und

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

zurückkehren würde @a

Das ist viel mehr der ‚Ruby Way‘ als verschachtelte Datenstrukturen mit Logik, die in Arrays auf Positionen beruht. Es dauert etwas mehr Arbeit am Anfang, aber Sie werden es viel besser auf lange Sicht finden.

Ruby ein sehr Objekt Programmiersprache orientiert und bietet eine sehr leistungsfähige Werkzeuge für Sie zu nutzen. Ich empfehle durchaus ein Buch wie „Die Programmiersprache Ruby“ oder „The Ruby Way“ lese einen richtigen Überblick über die Macht der Sprache zu erhalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top