2

我从 csv 文件中获取一些数据(以及如何在 csv 中选择前 20 个?),例如:

A B C
D E F

还有方法:

def common_uploader
    require 'csv'
    arr = CSV.read("/#{Rails.public_path}/uploads_prices/"+params[:file], {:encoding => "CP1251:UTF-8", :col_sep => ";", :row_sep => :auto, :headers => :none})  
    @csv = []
    @csv << arr
  end

所以它是数组数组...但是我如何在haml视图中正常查看它?如何查看数组数组?我尝试了类似的东西(也在每个文件中我有不同的列数):查看:

= @csv.first.each do |a|
 = a[:1]

请帮我查看csv数据。

4

3 回答 3

5

有几种方法可以读取一组记录,您需要根据数据源的预期大小来选择要使用的方法。

从 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>

我做了一个小改动,搬到街区arrayFile.open,没有什么不同。

于 2013-01-02T04:14:05.690 回答
0

你可以这样做:

arr = CSV.read("/data.csv", {:encoding => "CP1251:UTF-8", :col_sep => ",", :row_sep => :auto, :headers => :none})

i = 0
arr.each do |row|
  if i == 20
    break
  else
    i += 1
  end

  # do  sth
  puts row
end

但我认为这不是一个漂亮的解决方案。编辑:我不明白你为什么将 CSV 的实例放入数组中,你不会将 csv 文件的每一行放入数组中

于 2013-01-01T21:07:48.790 回答
-1
require 'csv'
def parser
  CSV.open('data.csv', 'r', ';') do |row|
  puts row
end
于 2013-01-01T22:36:32.460 回答