Tablice Ruby: select (), collect () i map ()

106

Składnia mapowania:

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

Zapytaj, czy mam:

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

Chcę usunąć każdy wpis, który ma pustą wartość ilości w tej tablicy lub wybrać tylko te z jakąś wartością.

Próbowałem:

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

Po prostu zwraca dużo fałszu, a kiedy używam tego samego, po prostu zmień mapę, aby wybrać, otrzymuję:

[]
ingalcala
źródło
Jeśli przyjrzysz się uważnie, wygląda na to, że jest to tablica skrótów
Emily
@Emily: To prawda, właśnie to sobie uświadomiłem. Ostatni przykład kodu sprawił, że pomyślałem inaczej, ponieważ :qtynawet tam nie występuje.
Niklas B.

Odpowiedzi:

131

Wygląda na to, że detailsjest to tablica skrótów. Więc itemwewnątrz twojego bloku będzie cały haszysz. Dlatego, aby sprawdzić :qtyklucz, wykonaj coś takiego:

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

To da ci wszystkie elementy, w których :qtyklucz nie jest pustym ciągiem.

oficjalna dokumentacja wyboru

Emilia
źródło
26

EDYCJA: Właśnie zdałem sobie sprawę, że chcesz filtrować details, co jest tablicą skrótów. W takim razie możesz to zrobić

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

Sama wewnętrzna struktura danych nie jest tablicą, ale skrótem. Możesz również użyć selecttutaj, ale w tym przypadku blok otrzymuje klucz i wartość:

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

Lub używając reject, co jest odwrotnością select(wyklucza wszystkie elementy, dla których zachodzi dany warunek):

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

Zauważ, że to jest Ruby 1.9. Jeśli musisz zachować zgodność z 1.8, możesz zrobić:

Hash[h.reject { |key, value| value.empty? }]
Niklas B.
źródło
@ingalcala: Właśnie zdałem sobie sprawę, że moja odpowiedź nie jest tym, czego potrzebujesz. Sprawdź moją edycję, aby dowiedzieć się, jak filtrować detailssamą tablicę.
Niklas B.
9

Kiedy masz do czynienia z hashem {}, użyj zarówno klucza, jak i wartości do bloku wewnątrz ||.

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

=>[false, false, true, false, false]
Michaela Berkowskiego
źródło