在Ruby中解析CSV,转换和排序为数组

时间:2016-09-21 02:08:46

标签: arrays ruby sorting csv

我正在努力解决编码问题,并且我一直试图对数据进行排序。

挑战在于:

  1. 解析数据并仅查找用户在9/6/10之前启动的行。
  2. 按升序排序“start_dates”。
  3. 从“字词”列返回/打印结果短语。
  4. 我能够得到正确的单词,但顺序不正确。

    start_dates需要按升序排序,以便单词以正确的顺序显示。

    这是我的代码:

    require 'CSV'
    
    csvFile = 'tse.csv'
    
    CSV.foreach(csvFile) do |row|
      int = row[13].to_i
      words = []
      if int < 1283731200
        words.push(row[16])
      end
      puts words
    end
    

    注意: 1283731200是我需要的日期的Unix时间戳。

    如何排序row[13]? sort方法的每个组合,但返回其中一个错误:

      

    未定义的方法'sort'为0:Fixnum(NoMethodError)

         

    “start_date”的未定义方法'sort':String(NoMethodError)

    CSV片段:

    id,created_at,first_name,last_name,email,gender,company,currency,drug_brand,drug_name,drug_company,pill_color,frequency,start_date,end_date,other,words,bitcoin,word
    676,1351140260,Charles,Rice,crice49@i2i.jp,Male,Realbuzz,MDL,Nortriptyline Hydrochloride,Nortriptyline Hydrochloride,"Physicians Total Care, inc.",Maroon,monthly,1409564900,1331661153,Monthly,aliquet,1AeYC1Cc49p7J5hFqUcsgJFjXb5Pqa68AQ,",./;'[]\-="
    2002,1540878657,Margaret,Day,mdaydp@salon.com,Female,Devbug,IDR,RENOKIN HAIR REVITALIZING CONDITIONER,Dimethicone,"Caregen Co., Ltd.",Yellow,monthly,1458457018,1533561260,Weekly,cursus,164X1tNoUguVA8Xpg2vnp3cfYzhTRGxwoN,<svg><script>0<1>alert('XSS')</script>
    3324,1589084473,Anthony,Collins,acollinsil@java.com,Male,Avamm,EUR,FRUITOPIA,PYRITHIONE ZINC,CVS PHARMACY,Blue,weekly,1333192422,1520700521,Never,pharetra,15oqV5seTTsQZDJhagJoU2z5hB9m7QCRAj,�_��_ۑ�Ӓ�ʑ��
    

1 个答案:

答案 0 :(得分:0)

所以,我修改了前两行的开始日期,使它们落在时间限制内。

供参考,这是我使用的csv文件。

id,created_at,first_name,last_name,email,gender,company,currency,drug_brand,drug_name,drug_company,pill_color,frequency,start_date,end_date,other,words,bitcoin,word
676,1351140260,Charles,Rice,crice49@i2i.jp,Male,Realbuzz,MDL,Nortriptyline Hydrochloride,Nortriptyline Hydrochloride,"Physicians Total Care, inc.",Maroon,monthly,1209564900,1331661153,Monthly,aliquet,1AeYC1Cc49p7J5hFqUcsgJFjXb5Pqa68AQ,",./;'[]\-="
2002,1540878657,Margaret,Day,mdaydp@salon.com,Female,Devbug,IDR,RENOKIN HAIR REVITALIZING CONDITIONER,Dimethicone,"Caregen Co., Ltd.",Yellow,monthly,1158457018,1533561260,Weekly,cursus,164X1tNoUguVA8Xpg2vnp3cfYzhTRGxwoN,<svg><script>0<1>alert('XSS')</script>
3324,1589084473,Anthony,Collins,acollinsil@java.com,Male,Avamm,EUR,FRUITOPIA,PYRITHIONE ZINC,CVS PHARMACY,Blue,weekly,1333192422,1520700521,Never,pharetra,15oqV5seTTsQZDJhagJoU2z5hB9m7QCRAj,�_��_ۑ�Ӓ�ʑ��

您的代码存在一些问题

1)您在words = []循环中声明了foreach,因此每次都会重置。你不希望这样。

2)您没有跟踪推入words数组的每个值的开始日期。

3)csv文件的第一行是标题,您没有在代码中考虑到这一点。

这就是我做的事情

require 'csv'

csvFile = 'test.csv'
words = {}
CSV.foreach(csvFile) do |row|
  next if row[0] == 'id'

  int = row[13].to_i
  if int < 1283731200
    words[row[13]] = row[16]
  end
end
words = words.sort.map(&:last) #=> ["cursus", "aliquet"]

在这种情况下我使用了哈希。所以你有一个starting_date => word的键值对。

next if row[0] == 'id检查我们是否在第一行。如果是,请跳到下一次迭代。

然后,最后一行,我对散列进行排序,它以[[starting_date1, word1], [starting_date2, word2]...]的形式返回一个数组,然后使用map选择最后一个值,即你想要的单词,所以通过开始日期,您最终会按升序排列一系列单词。