Array di Ruby: select (), collect () e map ()


106

La sintassi per la mappatura:

a = ["a", "b", "c", "d"]      #=> ["a", "b", "c", "d"] 
a.map {|item|"a" == item}     #=> [true, false, false, false] 
a.select {|item|"a" == item}  #=> ["a"]

Domanda che ne dici se ho:

 irb(main):105:0> details[1]
 => {:sku=>"507772-B21", :desc=>"HP 1TB 3G SATA 7.2K RPM LFF (3 .", :qty=>"", 
 :qty2=>"1", :price=>"5,204.34 P"}

Voglio eliminare ogni voce che ha un valore qty vuoto su questo array o selezionare solo quelli con un valore in esso.

Provai:

details.map {|item|"" == item}

Restituisce solo un sacco di false e poi quando uso lo stesso cambia mappa per selezionare ottengo:

[]

Se guardi da vicino, sembra che sia una serie di hash
Emily

@ Emily: Verissimo, me ne sono appena reso conto. L'ultimo esempio di codice mi ha fatto pensare diversamente, perché :qtynon appare nemmeno lì.
Niklas B.

Risposte:


131

Sembra che detailssia un array di hash. Quindi itemall'interno del tuo blocco ci sarà l'intero hash. Pertanto, per controllare la :qtychiave, dovresti fare qualcosa del genere:

details.select{ |item| item[:qty] != "" }

Questo ti darà tutti gli elementi in cui la :qtychiave non è una stringa vuota.

documentazione ufficiale selezionata


26

EDIT: ho appena capito che vuoi filtrare details, che è un array di hash. In quel caso potresti farlo

details.reject { |item| item[:qty].empty? }

La stessa struttura dati interna non è un array, ma un hash. Puoi anche usare selectqui, ma in questo caso al blocco viene data la chiave e il valore:

irb(main):001:0> h = {:sku=>"507772-B21", :desc=>"HP 1TB 3G SATA 7.2K RPM LFF (3 .", :qty=>"", :qty2=>"1", :price=>"5,204.34 P"}
irb(main):002:0> h.select { |key, value| !value.empty? }
=> {:sku=>"507772-B21", :desc=>"HP 1TB 3G SATA 7.2K RPM LFF (3 .", 
    :qty2=>"1", :price=>"5,204.34 P"}

O usando reject, che è l'inverso di select(esclude tutti gli elementi per i quali vale la condizione data):

h.reject { |key, value| value.empty? }

Nota che questo è Ruby 1.9. Se devi mantenere la compatibilità con 1.8, potresti fare:

Hash[h.reject { |key, value| value.empty? }]

@ingalcala: mi sono appena reso conto che la mia risposta non è effettivamente ciò di cui hai bisogno. Si prega di controllare la mia modifica per come filtrare l' detailsarray stesso.
Niklas B.

9

Quando si ha a che fare con un hash {}, utilizzare sia la chiave che il valore del blocco all'interno del file ||.

details.map {|key,item|"" == item}

=>[false, false, true, false, false]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.