在纯Ruby中排序巨大的CSV文件并与SQLesque类型目标

时间:2017-01-30 11:21:21

标签: ruby sorting csv

我几乎完成了这个csv操作,并且我在一段时间内没有使用ruby的过程中学到了很多,但我仍然不太确定如何

  1. 按升序对unix时间戳进行排序,从最低到最高
  2. THEN然后才执行#each块,我限制search_range,然后找出与unix时间戳关联的密钥。
  3. 示例,我现在知道在start_date和end_date之间有来自5000多行的csv的12行。每个时间戳都有一个与之关联的唯一键,但它必须按照开始日期或时间戳顺序排列。

    CSV文件如下所示:

    ID created_at  Key
    1  1309380645  rubbish
    2  1237178109  placeholder
    3  1303585711  examples
    4  1231175716  for learning
    

    以下是我的代码,感谢我早些时候的帮助:

    require 'csv'
    require 'date'
    
    start_date = DateTime.rfc3339('2014-06-22T00:00:00Z').to_time.to_i
    end_date = DateTime.rfc3339('2014-07-22T00:00:00Z').to_time.to_i
    
    keywords = []
    
    search_range = (start_date..end_date)
    
    my_csv = CSV.read('sample_data.csv', headers: true)
    
    sorted_csv = my_csv.sort {|a, b| a[1].to_i <=> b[1].to_i}
    
    sorted_csv.each do |row|
        next unless search_range.cover?(row['created_at'].to_i) 
        keywords << row['key']
    end
    
    puts keywords
    

    我可以确认,尽管我付出了最大努力,但目前按键仍然没有按顺序排列。任何帮助一如既往的赞赏

1 个答案:

答案 0 :(得分:1)

这应该可以正常工作,即使它对于巨大的CSV文件来说可能很慢,并且消耗了相当多的内存。请注意,此代码首先选择好行,然后对它们进行排序,以避免对整个CSV文件进行排序:

require 'csv'

amounts = []

start_date = Time.new(2012, 1, 22)
end_date   = Time.new(2014, 7, 22)

search_range = (start_date.to_i..end_date.to_i)

all_rows = CSV.read('data.csv', headers: true, skip_blanks: true)

good_rows = all_rows.select do |row|
  search_range.cover?(row['created_at'].to_i)
end

good_rows.sort_by! { |row| row['created_at'].to_i }

amounts = good_rows.map { |row| row['purchase_amt'] }

更新:&#39; created_at&#39;现在使用的是列,它是&#39; Unix_time&#39;在上一个问题中。