我的表字段名称是小写的,我从CSV文件中获得的字段名称是camelcase。无论如何我可以将哈希数组的键转换为小写吗?
以下是我现在的代码:
CSV.foreach(file, :headers => true) do |row|
Users.create!(row.to_hash)
end
这是失败的,因为密钥是驼峰式的(我通过手动编辑文件来验证这一点,使标题行全部小写)。
PS。另外,我很想知道为什么地狱之轨将表格字段名称的区分大小写开始起作用?
答案 0 :(得分:23)
您可以将header_converters选项与CSV一起使用:
CSV.foreach(file, :headers => true, :header_converters => lambda { |h| h.try(:downcase) }) do |row|
Users.create!(row.to_hash)
end
将.try放在那里很重要,因为空标头会引发异常。比在每一行上做得更好(也更快)。
答案 1 :(得分:14)
您可以使用以下内容:
CSV.foreach(file, :headers => true) do |row|
new_hash = {}
row.to_hash.each_pair do |k,v|
new_hash.merge!({k.downcase => v})
end
Users.create!(new_hash)
end
我没时间测试它,但你可以理解它。
希望它会有所帮助
答案 2 :(得分:5)
因为这是用Rails标记的。
使用ActiveSupport启动vom 3.0版,您可以使用HashWithIndifferentAccess
。
这将允许使用小写/大写/符号来访问键或哈希。
my_hash = { "camelCase": "some value" }
my_hash.with_indifferent_access[:camelcase] # 'some value'
my_hash.with_indifferent_access['camelcase'] # 'some value'
my_hash.with_indifferent_access['camelCase'] # 'some value'
my_hash.with_indifferent_access['CAMELCASE'] # 'some value'
ActiveSupport 4.0.2也介绍了这个:
my_hash.deep_transform_keys!(&:downcase)
# or if your hash isn't nested:
my_hash.transform_keys!(&:downcase)
答案 3 :(得分:3)
Ruby 1.9提供了一种非常好的方法来实现这一点,使用each_with_object来避免初始化临时变量。
CSV.foreach(file, :headers => true) do |row|
new_hash = row.each_with_object({}) do |(k, v), h|
h[k.downcase] = v
end
Users.create!(new_hash)
end
答案 4 :(得分:2)
我发现这种方法更优雅:
hash_with_camelcase_keys.to_a.map { |pair| [pair.first.downcase, pair.last] }.to_h
答案 5 :(得分:2)
您可以简单地做
hash.transform_keys(&:downcase)
将哈希键更改为小写,或者也可以根据需要将哈希值转换为小写或大写。
hash.transform_values(&:downcase)
或hash.transform_values(&:upcase)
hash = {:A=>"b", :C=>"d", :E=>"f"}
hash.transform_keys(&:downcase)
=> {:a=>"b", :c=>"d", :e=>"f"}
答案 6 :(得分:1)
我会直接添加哈希,比合并更有效!因为你没有为每一对创建一个新的哈希。
CSV.foreach(file, :headers => true) do |row|
new_hash = {}
row.to_hash.each_pair do |k,v|
new_hash[k.downcase] = v
end
Users.create!(new_hash)
end
答案 7 :(得分:1)
您可以考虑使用underscore
而不是downcase
,因为这也会将CamelCase
转换为camel_case
表示法,更像Ruby。
我的个人偏好是使用deep_transform_keys
: hash.deep_transform_keys{|key| key.underscore.to_sym }
由于transform_keys
不会遍历整个哈希。
答案 8 :(得分:0)
我发现这个解决方案明显更快,更“Rubyish”。
CSV.foreach(file, :headers => true) do |row|
new_hash = Hash[row.to_hash.map { |k, v| [k.downcase, v] }]
Users.create!(new_hash)
end