Ruby通过标头值解析csv

时间:2012-09-18 11:25:32

标签: ruby-on-rails ruby csv

我正在研究一种获取CSV文件(带标题)并使用Ruby CSV.parse解析它的方法,但我只想保存特定的列。

CSV看起来像这样:

NAME,SUPERNET_IP,POP_NAME,ADDRESS_BLOCK_START,ADDRESS_BLOCK_END,Service,ISP Service ID,WCC,DUNSID
Retail,186.43.168.0,text1,186.43.168.0,186.43.175.255,XYZ,XYZB00090095,Enabled,227015716
Retail,186.57.80.0,text2,186.57.80.0,186.57.87.255,XYZ,XYXB00090095,Enabled,227015716

我想要保留的唯一字段是:

POP_NAME,ADDRESS_BLOCK_START,ADDRESS_BLOCK_END,WCC

是否有办法通过特定的标题名称解析CSV,例如:

mycsv = CSV.parse(csv_data, {:headers => true, (list of headers to keep here) })

此示例假设csv_data是由上面的示例CSV形成的字符串。

作为权宜之计,我只是将CSV转换为阵列数组,但这并不是我所追求的。我宁愿把它保存为CSV对象。

myreturnedcsv = []
mycsv = CSV.parse(csv_data, {:headers => true, })
mycsv.each do |row|
  myreturnedcsv.push([row[2], row[3], row[4],row[7]])
end

2 个答案:

答案 0 :(得分:5)

请尝试smarter_csv gem /解析器。这有能力忽略"列"在输入(删除列)https://github.com/tilo/smarter_csv

答案 1 :(得分:2)

仅使用stdlib,您可以在列模式下使用CSV::Table个对象进行操作 (而不是默认的混合模式)。在列模式下,迭代方法 将产生两个元素元组,其中包含列名和值数组 该专栏。

考虑到这一点,我们可以写出类似的东西:

# column names to keep
columns_to_keep = %w(POP_NAME ADDRESS_BLOCK_START ADDRESS_BLOCK_END WCC)

# get the data
mycsv = CSV.parse(csv_data, :headers => true)

# change to column mode, filter by column name and change back to default
# mode of operation
mycsv.by_col!.delete_if do |col_name, col_values|
  !columns_to_keep.include?(col_name)
end.by_col_or_row!   

最后一步是可选的,只是将表对象保留为默认模式 我们可以照常迭代(按行)。

我实际上并不知道这种方法是否会受到perf / mem问题的影响 处理大数据集。

您可以在CSV::Table的文档中找到有关行/列/混合访问的详细信息。

希望它有所帮助。