HASH SELECT de los indices en un ARRAY


#1

Hola, a todos.

Estoy probando de seleccionar los registros de un HASH que estan
indicados en un ARRAY y que retorne un HASH con los registros
seleccionados.

fields=[‘DNI’, ‘ID’, ‘NOMCOM’]
data={:DNI => “444444444Q”, :ID => 123, :NOMCOM => “nombre comercial del
123”, :DIRECTOR => “Director del 123”}

EJEMPLO1:
fields.each { |field| data.select {|k,v| k==field.to_sym }}

Evidentemente, al hacer la instruccion anterior, me devuelve solo las
keys.

A partir de aqui he visto que la instruccion debe partir del HAS.SELECT,
como:

EJEMPLO2:
data.select {|k,v| k==fields[0].to_sym}

Pero no he sabido como buclar el array fields dentro del bloque del
select.

Como se puede hacer para que devuelva un array de parejas key,value (en
el ejemplo1) o para que devuelva un HASH con los registros seleccionados
(en el ejemplo 2)?

Muchas gracias.
Rafa.


#2

Te doy una alternativa, a ver que te parece…

fields.inject({}){|hash, field| hash[field.to_sym] = data[field.to_sym];
hash}

Espero haber entendido el problema :slight_smile:

Suerte,
Juan.

2009/6/3 Rafa C. removed_email_address@domain.invalid


#3

Juan G. galisteo wrote:

Te doy una alternativa, a ver que te parece…

fields.inject({}){|hash, field| hash[field.to_sym] = data[field.to_sym];
hash}

Espero haber entendido el problema :slight_smile:

Suerte,
Juan.

2009/6/3 Rafa C. removed_email_address@domain.invalid

Me has entendido perfectamente. Pero me gustaria hacerte otra pegunta.
Por que
si ejecuto el codigo anterior sin ‘;hash’ en el irb da un error? No
deberia de retornar ‘hash’ que es la nueva variable definida en inject?

fields.inject({}){|hash, field| hash[field.to_sym] = data[field.to_sym]}


#4

Buenas,

otro método un poco más “sencillo”:

data.reject {|k,v| !fields.include?(k.to_s)}

Básicamente reject devuelve un hash con los elementos “descartados”
por el bloque, o sea que si descartas las keys que tienes en el array,
de devuelve el hash que esperas.

Espero te sirva de ayuda!

Saludos,

Isaac Feliu


#5

Juan G. galisteo wrote:

Básicamente por la forma en la que trabaja el método inject. El valor
conel
que va trabajando es el resultado de la iteración anterior. El primero
esta
inicializado con inject({}).

Fíjate que pasa si haces hash[:uno] = 1 en irb; te devuelve 1, verdad?
Dentro
del inject, en la siguiente iteración, usarías ese 1 como hash y
obtendrás
un
fantástico error :slight_smile:

Devolviendo explícitamente el hash subsanamos el problema :slight_smile:

Te lo he aclarado algo?

Un saludo,
Juan.

2009/6/3 Rafa C. removed_email_address@domain.invalid

Entendido y muchas gracias.
Rafa.


#6

Básicamente por la forma en la que trabaja el método inject. El valor
conel
que va trabajando es el resultado de la iteración anterior. El primero
esta
inicializado con inject({}).

Fíjate que pasa si haces hash[:uno] = 1 en irb; te devuelve 1, verdad?
Dentro
del inject, en la siguiente iteración, usarías ese 1 como hash y
obtendrás
un
fantástico error :slight_smile:

Devolviendo explícitamente el hash subsanamos el problema :slight_smile:

Te lo he aclarado algo?

Un saludo,
Juan.

2009/6/3 Rafa C. removed_email_address@domain.invalid


#7

2009/6/3 Rafa C. removed_email_address@domain.invalid:

Entendido y muchas gracias.
Rafa.

Si estás en Rails, active support define Hash#slice que es exactamente
lo que quieres:

{:foo => 1, :bar => ‘paco’, :wadus => true}.slice(:bar, :wadus)
=> {:wadus=>true, :bar=>“paco”}


Sergio Gil Pérez de la Manga
e-mail > removed_email_address@domain.invalid
blog > http://www.lacoctelera.com/porras
now > http://twitter.com/porras


#8

On Thu, Jun 4, 2009 at 10:12 AM, Rafa C.
removed_email_address@domain.invalid wrote:

{:foo => 1, :bar => ‘paco’, :wadus => true}.slice(:bar, :wadus)
123", :DIRECTOR => “Director del 123”}

Pero como puedo buclar el array fields en el parametro slice
data.slice(fields.each do {|x| x.to_sym}) (?)

data.slice(*fields)

http://4loc.wordpress.com/2009/01/16/the-splat-operator-in-ruby/


Sergio Gil Pérez de la Manga
e-mail > removed_email_address@domain.invalid
blog > http://www.lacoctelera.com/porras
now > http://twitter.com/porras


#9

Sergio Gil Pérez de la Manga wrote:

{:foo => 1, :bar => ‘paco’, :wadus => true}.slice(:bar, :wadus)

Pero como puedo buclar el array fields en el parametro slice
data.slice(fields.each do {|x| x.to_sym}) (?)

data.slice(*fields)

http://4loc.wordpress.com/2009/01/16/the-splat-operator-in-ruby/

data.slice(*fields.collect{|f| f.to_sym})

o (ya que estamos con activesupport)

data.stringify_keys.slice(*fields)


#10

Sergio Gil Pérez de la Manga wrote:

2009/6/3 Rafa C. removed_email_address@domain.invalid:

Entendido y muchas gracias.
Rafa.

Si est�s en Rails, active support define Hash#slice que es exactamente
lo que quieres:

{:foo => 1, :bar => ‘paco’, :wadus => true}.slice(:bar, :wadus)
=> {:wadus=>true, :bar=>“paco”}


Sergio Gil P�rez de la Manga
e-mail > removed_email_address@domain.invalid
blog > http://www.lacoctelera.com/porras
now > http://twitter.com/porras

fields=[‘DNI’, ‘ID’, ‘NOMCOM’]
data={:DNI => “444444444Q”, :ID => 123, :NOMCOM => “nombre comercial del
123”, :DIRECTOR => “Director del 123”}

Pero como puedo buclar el array fields en el parametro slice
data.slice(fields.each do {|x| x.to_sym}) (?)