Domanda

dire Let Ho la seguente matrice:

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

e voglio trovare l'elemento minimo, confrontando il secondo elemento degli elementi. L'elemento minimo sarà [5, 1] poiché 1 è inferiore 7. Posso utilizzare il seguente codice:

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

Per calcolare il massimo, posso fare lo stesso:

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

Questo dà [2, 7].

Io uso lo stesso blocco di tutto il tempo. Mi piacerebbe avere quel blocco da qualche parte e fornire alla funzione min / max. Speravo qualcosa di simile:

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

avrebbe funzionato, ma non lo fece. Qualche idea su come posso fare questo?

È stato utile?

Soluzione

Utilizzare l'operatore & per trasformare un oggetto Proc in un blocco.

arr.min &blo

Altri suggerimenti

@ di sepp2k risposta è quella più generale, ma nel tuo caso specifico, vorrei solo usare

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

poiché è molto più evidente di tutte quelle parentesi graffe e parentesi quadre e indici di array galleggiando.

Se tutto ciò che serve è minimo e massimo, si potrebbe utilizzare Enumerable#minmax metodo e calcolare sia in una sola volta:

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

Modifica: L'inferno, ho appena notato c'è anche minmax_by, in modo da poter combinare con il metodo last, e dispongono di:

min, max = arr.minmax_by &:last

come su questo?

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

Una soluzione più generale a problemi come questo per evitare matrici nidificate interamente ed usare una classe invece. È quindi possibile definire il <=> dell'operatore per quella classe, che vi dà accesso a tutte le funzioni del mixin comparabili (http://ruby-doc.org/core/classes/Comparable.html) ti dà il <, <= , ==,> = e> gli operatori e il metodo di 'mezzo?'

Questa è solo un esempio, nella vita reale si usa classi che descrivono ciò che immagazzinano:

class Duo

  include Comparable

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

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

end

Se si dispone di una serie di Duo oggetto è quindi possibile utilizzare le Min, Max, e funzioni di ordinamento senza dover definire l'operatore di confronto. Quindi ...

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

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

restituirebbe l'array [@c, @b, @a]

E

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

sarebbe tornato @a

Questo è molto di più il 'Rubino Way' di nidificato data-strutture con la logica che si basa su posizioni in array. Ci vuole un po 'più di lavoro all'inizio, ma lo troverete molto meglio nel lungo periodo.

Ruby è un oggetto molto orientato la programmazione lingua e fornisce strumenti molto potenti per l'uso. Raccomando la lettura di un libro come "The Ruby Programming Language" o "The Way Ruby" per avere una corretta visione d'insieme il potere della lingua.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top