Ruby on rails CSV::行和散列导航不工作Ruby 2.3.3 Rails 5.1

Ruby on rails CSV::行和散列导航不工作Ruby 2.3.3 Rails 5.1,ruby-on-rails,ruby,csv,parsing,hash,Ruby On Rails,Ruby,Csv,Parsing,Hash,我已经使用csv.parse解析了一个csv,并且正在逐行导航它。因此,我们正在查看的对象是一个名为Row的CSV::Row 这是我尝试浏览行时发生的情况的屏幕截图: 正如您所看到的,我可以调用.headers(),正如您所期望的那样,应变在列表中 当您查看对象本身时,您可以看到“应变”:“818头带” 所以行['Strain']应该等于8181头带,除非它返回nil 自然地,我尝试了row.Strain,row[“Strain”],row[Strain],row[:Strain]这些都不起作

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

这是我尝试浏览
行时发生的情况的屏幕截图:

正如您所看到的,我可以调用
.headers()
,正如您所期望的那样,
应变
在列表中

当您查看对象本身时,您可以看到
“应变”:“818头带”

所以
行['Strain']
应该等于
8181头带
,除非它返回
nil

自然地,我尝试了
row.Strain
row[“Strain”]
row[Strain]
row[:Strain]
这些都不起作用

我还认为它可能包含在一个单条目数组中,所以我尝试了
行[0]['Strain']
,结果也返回了
nil
,这并不奇怪

假设问题出在
CSV::Row
对象上,我调用
Row\u hash=Row.to\u hash()
将对象作为散列获取

既然我们使用了基本的ruby,那么像
row\u hash['Strain']
这样的普通调用就可以正常工作了?!?不。仍然
nil

我很困惑,这根本不是复杂的代码。
Hash
CSV::Row
的文档都将
[]
列为一种方法,而我在谷歌上搜索到的所有文章都将
Row['key']
列为正确的格式……但它对我不起作用

请帮助,我有一系列的CSV,我需要用它们来种子数据库,如果我不能导航哈希,我就不能这样做

2018年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
这不可能是对的

2018年5月15日下午1:05编辑:

$=irb(主)

$csv\u text=File.read('strain\u data\u formatted.csv'))
=> ... (它将整个csv转储到控制台)
$csv=csv.parse(csv_text,:headers=>true,:encoding=>ISO-8859-1)
=> #
$csv.first
=>#零
$csv.headers.first
=>“应变”
$csv.first[csv.headers.first]
=>“818头带”
$csv.headers.first.class
=>字符串
$“应变”。类别
=>字符串
$csv.headers.first==“应变”
=>错误
$csv.headers.first
=>“应变”

csv.headers.first
是一个值为“应变”的字符串,但它不等于值为“应变”的字符串

简单的石灰为我指明了正确的方向!谢谢大家!

问题在于,当标题打印为字符串时,隐藏字符无法呈现。这就是为什么
csv.first[csv.headers.first]
有效,但
csv.first[“应变”]
无效,即使
csv.headers.first
返回
“应变”
。大概它真正返回的是类似于
“invisiblestuffStrain”
(夸张了,但你明白了)

若要检查并查看您的情况是否如此,请调用标头上的
.bytes
方法,然后再次调用您期望的字符串值,例如
“应变”。bytes
。如果存在任何差异,则表示您具有隐藏字符

以下是我的实际控制台输出:

$ csv.headers.first.bytes
=> [239, 187, 191, 83, 116, 114, 97, 105, 110]
$ "Strain".bytes
=> [83, 116, 114, 97, 105, 110]
您可以看到为该对象存储的3个额外字符在呈现为字符串时不会显示

Simple Lime说:“您需要
gsub
将它们删除或删除原始csv中的文本,然后手动重新键入,以确保不添加任何额外内容”

对我来说,我必须直接从文本编辑器修改
.csv
,而不是使用excel并将其保存为
.csv


编辑:我发现从MS Excel中的
.xlsx
工作簿保存到
.csv
是导致这些奇怪字符出现的原因。我不得不编辑这个文件,所以我重新打开并保存了它,当我重新播种时又出现了同样的错误。与以前一样,从文本编辑器中重新键入第一个标题解决了这个问题。

您可以使用gsub方法删除额外的不可见字符

gsub("\xEF\xBB\xBF","")
该文件包含一个


有很多方法可以删除它。参见

上的答案我还以为我也有你的问题,直到我意识到Ruby没有正确分割列。我把我的解决方案放在这里,以防其他人陷入同样的境地。我只需要添加
col\u sep
属性,如下所示:
CSV.parse('file_name',headers:true,encoding:'ISO-8859-1',col_sep:';')

行的输出是什么。has_key?(“应变”)
。另外,您是否尝试过使用
每个
对该行进行迭代,是否可以打印出该行中每个元素的键值?看起来你的代码应该可以工作。您是否尝试过在没有Rails的常规IRB会话中解析CSV?您的环境中可能有某种原因导致出现奇怪的结果
行[row.headers.first]
返回正确的结果?
row.headers.first.bytes
看起来像什么?(也请将代码添加为文本(使用代码格式按钮)而不是图像)Leo-
行。是否有键?(“应变”)
返回
false
我很惊讶,我们可以将“应变”作为选项之一。我还没有试着对每一行进行迭代,我现在就试试。我也没有尝试过简单的IRB,所以我也可以尝试一下。莱姆-
行[row.headers.first]
返回
818头带“
,这是令人惊讶的,因为
行.headers.first
返回
“应变”
,但
行[“应变”]
仍然返回
@IanBrooks
行.headers.first.bytes
行.headers.first.codepoints
?这些将告诉您标题中是否有任何隐藏/不可见字符。如果有,您需要
gsub
将其删除或删除原始csv中的文本,并手动重新键入,以确保没有额外的内容被添加请不要只发布对其他堆栈交换问题的链接答案。相反,在这里包含答案的基本部分,并根据具体问题定制答案
gsub("\xEF\xBB\xBF","")