Tengo un archivo CSV con dos columnas:

PPS_Id Amount
123    100
1234   150

Leí datos de este archivo e inserto en una matriz usando el código a continuación:

CSV.foreach("filename.CSV", headers: true) do |row|
  file_details << row.inspect # hash
end

Luego trato de insertar los datos en file_details en un hash con PPS_Id como clave y Amount como Valor, estoy usando el siguiente código:

file_details_hash = Hash.new

file_details.each { |x|  
  file_details_hash[x['PPS_Id']] = x['Amount']
}

Pero cuando imprimo el resultado no obtengo nada solo {"PPS_Id"=>"Amount"}

¿Puedes ayudar por favor?

3
d_luffy_de 27 dic. 2016 a las 15:10

3 respuestas

La mejor respuesta

Su código, modificado para funcionar

Debe especificar el separador de columna para su csv y eliminar inspect.

require 'csv'

file_details = []
CSV.foreach("filename.CSV", headers: true, col_sep: "\s" ) do |row|
  file_details << row
end

file_details_hash = Hash.new
file_details.each { |x|
  file_details_hash[x['PPS_Id']] = x['Amount']
}

p file_details_hash
#=> {"123"=>"100", "1234"=>"150"}

Ahora devuelve lo que esperaba obtener.

Solución más corta

Lea el csv, suelte la primera línea (encabezado) y conviértalo en un hash:

p CSV.read("filename.CSV", col_sep: "\s").drop(1).to_h
#=> {"123"=>"100", "1234"=>"150"}
1
Eric Duminil 27 dic. 2016 a las 14:51

En primer lugar, está recopilando cadenas en una matriz (consulte String#inspect):

file_details << row.inspect

Después de eso, llame (sic!) {{ X0}} en esas cadenas:

x['PPS_Id'] #⇒ "PPS_Id", because string contains this substring

Dicho esto, su código no tiene más que errores. Puede lograr lo que quiere con:

csv = CSV.parse(File.read("filename.CSV"), col_sep: "\s")
csv[1..-1].to_h
#⇒ {
#    "123" => "100",
#   "1234" => "150"
# }
1
Aleksei Matiushkin 27 dic. 2016 a las 12:25

El uso de inspect guardará sus filas CSV como cadenas, por lo que obviamente no podrá obtener lo que necesita. En su lugar, intente esto:

file_details = CSV.read("filename.csv")

Leer CSV directamente creará una matriz 2D que luego puede iterar, que se verá así: [["PPS_Id", "Amount"], ["123", "100"], ["1234", "150"]]

Desde allí, puede modificar ligeramente su enfoque:

file_details.each do |key, value|
  file_details_hash[key] = value
end

Para recibir un hash como este: {"PPS_Id"=>"Amount", "123"=>"100", "1234"=>"150"}

1
Maxim Fedotov 27 dic. 2016 a las 12:32