Ruby Array: pilih (), kumpulkan (), dan peta ()

106

Sintaks untuk pemetaan:

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

Pertanyaan bagaimana jika saya memiliki:

 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"}

Saya ingin menghapus setiap entri yang memiliki nilai qty kosong pada larik ini atau hanya memilih yang memiliki beberapa nilai di dalamnya.

Saya mencoba:

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

Hanya mengembalikan banyak kesalahan dan kemudian ketika saya menggunakan yang sama hanya mengubah peta untuk memilih saya dapatkan:

[]
ingalcala.dll
sumber
Jika Anda melihat lebih dekat, sepertinya itu adalah serangkaian hash
Emily
@Emily: Benar sekali, saya baru menyadarinya. Contoh kode terakhir membuat saya berpikir sebaliknya, karena :qtybahkan tidak muncul di sana.
Niklas B.

Jawaban:

131

Sepertinya detailsadalah serangkaian hash. Jadi itemdi dalam blok Anda akan ada seluruh hash. Oleh karena itu, untuk memeriksa :qtykunci tersebut, Anda akan melakukan sesuatu seperti berikut:

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

Itu akan memberi Anda semua item di mana :qtykuncinya bukan string kosong.

dokumentasi pemilihan resmi

Emily
sumber
26

EDIT: Saya baru menyadari Anda ingin memfilter details, yang merupakan array hashes. Dalam hal ini Anda bisa melakukannya

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

Struktur data bagian dalam itu sendiri bukanlah Array, tetapi Hash. Anda juga dapat menggunakan di selectsini, tetapi blok diberi kunci dan nilai dalam kasus ini:

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"}

Atau menggunakan reject, yang merupakan kebalikan dari select(tidak termasuk semua item yang kondisi tertentu berlaku):

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

Perhatikan bahwa ini adalah Ruby 1.9. Jika Anda harus menjaga kompatibilitas dengan 1.8, Anda dapat melakukan:

Hash[h.reject { |key, value| value.empty? }]
Niklas B.
sumber
@ingalcala: Saya baru menyadari bahwa jawaban saya sebenarnya bukanlah yang Anda butuhkan. Silakan periksa hasil edit saya untuk mengetahui cara memfilter detailsarray itu sendiri.
Niklas B.
9

Saat menangani hash {}, gunakan kunci dan nilai ke blok di dalam ||.

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

=>[false, false, true, false, false]
Michael Berkowski
sumber