有几种方法可以读取一组记录,您需要根据数据源的预期大小来选择要使用的方法。
从 CSV 文件开始:
A1,A2,A3
B1,B2,B3
C1,C2,C3
D1,D2,D3
E1,E2,E3
F1,F2,F3
读取固定数量的记录的最简单方法是以下之一:
require 'csv'
array = CSV.read('test.csv')[0, 2]
它返回一个包含两个子数组的数组:
[
[0] [
[0] "A1",
[1] "A2",
[2] "A3"
],
[1] [
[0] "B1",
[1] "B2",
[2] "B3"
]
]
一个替代方案是:
File.new('test.csv').readlines[0, 2].map{ |l| CSV.parse(l).flatten }
它返回相同的结果,一个包含两个子数组的数组:
[
[0] [
[0] "A1",
[1] "A2",
[2] "A3"
],
[1] [
[0] "B1",
[1] "B2",
[2] "B3"
]
]
这两种方法都适用于小型输入文件,但如果您从大型输入文件中读取几行,则会出现问题。它们将强制 Ruby 将整个文件读入内存并创建一个中间数组,然后再切掉所需的记录数。在我工作的地方,获得千兆字节的文件大小对我们来说没什么,所以抓取这些文件的一小部分会使 Ruby 和系统做大量的工作来构建中间数组,然后把它扔掉。
您最好只读取所需的最少记录数。有时需要在阅读前跳过几行;这证明了这个想法,以及EOFError
意外遇到输入文件的 EOF 时的处理:
File.open('test.csv') do |fi|
array = []
begin
5.times { fi.readline }
2.times.each{ array += CSV.parse(fi.readline) }
rescue EOFError
end
end
替换5
为要跳过的记录2
数和要读取的记录数。对于那个例子,我特意读了文件的结尾来展示如何跳过行,读一些然后干净地处理 EOF 情况。
数据如下:
[
[0] [
[0] "F1",
[1] "F2",
[2] "F3"
]
]
因为我使用File.open
的是块,所以在块存在后文件会自动关闭,避免留下一个打开的文件句柄。
您问题的 HAML 输出部分根本没有明确定义,但这是输出数据的一种方法:
array = []
File.open('test.csv') do |fi|
begin
0.times { fi.readline }
2.times.each{ array += CSV.parse(fi.readline) }
rescue EOFError
end
end
require 'haml'
engine = Haml::Engine.new(<<EOT)
%html
%body
%table
- array.each do |r|
%tr
- r.each do |c|
%td= c
EOT
puts engine.render(Object.new, :array => array)
这导致了一个简单的 HTML 表的输出:
<html>
<body>
<table>
<tr>
<td>A1</td>
<td>A2</td>
<td>A3</td>
</tr>
<tr>
<td>B1</td>
<td>B2</td>
<td>B3</td>
</tr>
</table>
</body>
</html>
编辑:
和我的测试文件:dl.dropbox.com/u/59666091/qnt_small.csv 我想在浏览器中查看这 7 列(通过 haml 视图)
使用它作为我的测试数据:
a1,a2,a3,a4,a5,a6,a7
b1,b2,b3,b4,b5,b6,b7
c1,c2,c3,c4,c5,c6,c7
d1,d2,d3,d4,d5,d6,d7
e1,e2,e3,e4,e5,e6,e7
这个代码:
require 'csv'
array = []
File.open('test.csv') do |fi|
begin
0.times { fi.readline }
2.times.each{ array += CSV.parse(fi.readline) }
rescue EOFError
end
end
require 'haml'
engine = Haml::Engine.new(<<EOT)
%html
%body
%table
- array.each do |r|
%tr
- r.each do |c|
%td= c
EOT
puts engine.render(Object.new, :array => array)
我得到这个输出:
<html>
<body>
<table>
<tr>
<td>a1</td>
<td>a2</td>
<td>a3</td>
<td>a4</td>
<td>a5</td>
<td>a6</td>
<td>a7</td>
</tr>
<tr>
<td>b1</td>
<td>b2</td>
<td>b3</td>
<td>b4</td>
<td>b5</td>
<td>b6</td>
<td>b7</td>
</tr>
</table>
</body>
</html>
我做了一个小改动,搬到街区array
外File.open
,没有什么不同。