CSV ::行和哈希导航不工作Ruby 2.3.3 Rails 5.1

时间:2018-05-14 16:02:35

标签: ruby-on-rails ruby csv parsing hash

我使用CSV.parse解析了一个csv,并逐行导航。因此,我们正在查看的对象是名为CSV::Row

row

这是我尝试导航row时会发生什么情况的屏幕截图: screenshot

如您所见,我可以致电.headers(),因为您希望Strain在列表中

当您查看对象本身时,您可以看到"Strain":"818 Headband"

所以row['Strain']应该等于8181 Headband,除非它返回nil

当然,我尝试了row.Strainrow["Strain"]row[Strain]row[:Strain]没有一个有效。

我还认为它可能包含在单项数组中,因此我尝试row[0]['Strain']并且还返回nil,这并不奇怪。

假设问题出在CSV::Row对象上,我调用row_hash = row.to_hash()将对象作为哈希值。

现在我们已经处于基本的红宝石中,当然正常的通话如row_hash['Strain']会正常工作吗?!?不。仍nila view of row_hash

我感到很困惑,这根本不是复杂的代码。 HashCSV::Row的文档都列出了[]作为一种方法,而我搜索过的所有文章都列出了row['key']作为正确的格式...除了它不适合我。

请帮助,我有一系列这些csvs,我需要为数据库播种,如果我无法浏览哈希值,我就无法做到这一点!

编辑时间:5月15日下午12:51:

csv.each do |row|
  row.each do |key, value|
    binding.pry
  end
end

$ key
=> "Strain"
$ value
=> "818 Headband"
$ row["Strain"]
=> nil

这不对......

编辑时间:5月15日下午1:05:

$ = irb(main)

$ csv_text = File.read('strain_data_formatted.csv')
=> ... (it dumped the whole csv to console)
$ csv = CSV.parse(csv_text, :headers => true, :encoding => 'ISO-8859-1')
=> #<CSV::Table mode:col_or_row row_count:118>
$ csv.first
=> #<CSV::Row "Strain":"818 Headband" "Subspecies":nil "Heritage":nil... 
$ csv.first["Strain"]
=> nil
$ csv.headers.first
=> "Strain"
$ csv.first[csv.headers.first]
=> "818 Headband"
$ csv.headers.first.class
=> String
$ "Strain".class
=> String
$ csv.headers.first == "Strain"
=> false
$ csv.headers.first
=> "Strain"

csv.headers.first如何是一个值为&#34; Strain&#34;的字符串。但它并不等于带有值的字符串&#34; Strain&#34;?!?

4 个答案:

答案 0 :(得分:1)

Simple Lime指出了正确的方法!谢谢!

问题是当标题打印为字符串时,有些隐藏字符无法呈现。这就是为什么csv.first[csv.headers.first]有效,但csv.first["Strain"]没有,即使csv.headers.first返回"Strain"。据推测它真正归还的是"invisiblestuffStrain"(夸大但你明白了)。

要检查并确定是否属于这种情况,请在标题上调用.bytes方法,然后再次对您希望的字符串值.bytes调用"Strain".bytes$ csv.headers.first.bytes => [239, 187, 191, 83, 116, 114, 97, 105, 110] $ "Strain".bytes => [83, 116, 114, 97, 105, 110] 。如果有任何差异,您有隐藏的字符。

这是我的实际控制台输出:

gsub

您可以看到为该对象存储的3个额外字符在呈现为字符串时无法显示。

Simple Lime说:“你需要.csv将它们删除或删除原始csv中的文本并手动重新输入,以确保不会添加额外的内容”

对我来说,我必须直接从我的文本编辑器中修改.csv,并将其保存为.xlsx

编辑:我发现从MS Excel中的.csv工作簿保存到CallLength(varchar(10)) and CallLengthActual(varchar(10)) 是导致这些奇怪字符出现的原因。我必须编辑文件,以便重新打开并重新保存,并在重新播种时再次出现相同的错误。和以前一样,从文本编辑器重新键入第一个标题可以解决问题。

答案 1 :(得分:1)

您可以使用gsub方法删除多余的不可见字符

gsub("\xEF\xBB\xBF","")

答案 2 :(得分:0)

文件包含UTF-8 BOM

有多种方法可以将其删除。查看有关How can I remove the BOM from a UTF-8 file?

的答案

答案 3 :(得分:0)

我以为我也遇到了您的问题,直到我意识到 Ruby 没有正确拆分列。我把我的解决方案放在这里,以防其他人陷入同样的​​情况。我需要添加的只是 col_sep 属性,如下所示: CSV.parse('file_name', headers: true, encoding: 'ISO-8859-1', col_sep: ';')