HASH SELECT de los indices en un ARRAY

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.

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. [email protected]

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. [email protected]

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

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

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. [email protected]

Entendido y muchas gracias.
Rafa.

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. [email protected]

2009/6/3 Rafa C. [email protected]:

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 > [email protected]
blog > http://www.lacoctelera.com/porras
now > http://twitter.com/porras

On Thu, Jun 4, 2009 at 10:12 AM, Rafa C.
[email protected] 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)


Sergio Gil Pérez de la Manga
e-mail > [email protected]
blog > http://www.lacoctelera.com/porras
now > http://twitter.com/porras

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)

The splat operator in Ruby | 4 Lines of Code

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

o (ya que estamos con activesupport)

data.stringify_keys.slice(*fields)

Sergio Gil Pérez de la Manga wrote:

2009/6/3 Rafa C. [email protected]:

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 > [email protected]
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}) (?)