Matrizes de Ruby: seleccione (), recolha () e mapa()

sintaxe para mapeamento:

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

Pergunta e se eu tiver:

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

quero apagar todos os itens que tenham um valor qty vazio nesta lista, ou seleccionar apenas os que tenham algum valor nela.

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

apenas devolve um monte de falso. e então quando eu usar o mesmo apenas mudar o mapa para selecionar eu recebo:

[]
 77
Author: John Topley, 2012-03-29

3 answers

Parece que details é um conjunto de traços. Então item dentro do teu bloco estará toda a haxixe. Portanto, para verificar a chave :qty, você faria algo como o seguinte:
details.select{ |item| item[:qty] != "" }

Isso dar-lhe-á todos os itens em que a tecla :qty não é um texto vazio.

 86
Author: Emily, 2012-03-28 21:07:58

EDIT: acabei de perceber que você quer filtrar {[[4]}, que é um conjunto de traços. Nesse caso você poderia fazer

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

A estrutura de dados interna em si não é um Array, mas um Hash. Você também pode usar select aqui, mas ao bloco é dada a chave e o valor neste caso:

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

Ou usando reject, que é o inverso de select (exclui todos os itens para os quais a condição dada se mantém):

h.reject { |key, value| value.empty? }
Note que este é o Ruby 1.9. Se tiver de manter compatibilidade com o 1, 8, pode fazer:
Hash[h.reject { |key, value| value.empty? }]
 16
Author: Niklas B., 2012-03-28 21:08:34

Ao lidar com um hash {}, use tanto a chave como o valor do bloco dentro do ||.

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

=>[false, false, true, false, false]
 6
Author: Michael Berkowski, 2012-03-28 21:02:34