以类似的方式输出到csv' print'输出到终端?

时间:2016-06-06 23:56:05

标签: ruby csv

我的ruby代码中包含的逻辑有点难以转换为csv输出,有没有办法以类似的方式追加每个ActionResult Create (int id) { ... }value在输出到终端时有效?

cop_log是数千条记录的哈希

print

目前在终端输出像这样,我希望它以同样的方式打印到csv:

cop_log = { 'A1' => 'val1', 'B1' => 'val2', 'C1' => 'val3', 'D1' => 'val4, 'E1' => 'val5', 'F1' => 'val6', 'G1' => 'val7', 'H1' => 'val8', 'I1' => 'val9', 'J1' => 'val10, 'K1' => 'val11', 'A2' => 'val12', 'B2' => 'val13', 'C2' => 'val14', 'D2' => 'val15, 'E2' => 'val16', 'F2' => 'val17', 'G2' => 'val18', 'H2' => 'val19', 'I2' => 'val20', 'J2' => 'val21, 'K2' => 'val22'}

cop_log.each do |key, value|
  if key.include?('K')
    print "#{value}\n"
  elsif key.include?('A')
    print "#{job_number},#{pm_lookup[job_number]},#{value},"
  elsif key.include?('B') || key.include?('C') || key.include?('D') ||
        key.include?('E') || key.include?('F') || key.include?('G') ||
        key.include?('H') || key.include?('I') || key.include?('J')
    print "#{value},"
  end
end

阅读文档,看起来常见的路线是执行以下操作,

val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11
val12, val13, val14, val15, val16, val17, val18, val19, val10, val21, val22
不幸的是,我的代码结构会让这有点困难......

4 个答案:

答案 0 :(得分:1)

这非常令人困惑,如果清理,将有助于使您的代码更具可读性和可维护性:

if key.include?('K')
  print "#{value}\n"
elsif key.include?('A')
  print "#{job_number},#{pm_lookup[job_number]},#{value},"
elsif key.include?('B') || key.include?('C') || key.include?('D') ||
  key.include?('E') || key.include?('F') || key.include?('G') ||
  key.include?('H') || key.include?('I') || key.include?('J')
  print "#{value},"
end

什么是key?一串字符还是一个字符?如果您匹配单个字符,则可以执行以下操作:

if key == 'K'
  print "#{value}\n"
elsif key == 'A'
  print "#{job_number},#{pm_lookup[job_number]},#{value},"
elsif ('B'.. 'J').include?(key)
elsif 
  print "#{value},"
end

甚至转换:

elsif ('B'.. 'J').include?(key)

为:

elsif ('B'..'J') === key

如果你在字符串中搜索字符匹配:

if key['K']
  print "#{value}\n"
elsif key['A']
  print "#{job_number},#{pm_lookup[job_number]},#{value},"
elsif key[/[B-J]/]
  print "#{value},"
end

此时您已准备好解决清理CSV输出问题。我建议在课程文档中重新使用the basic examples CSV输出之一。我还建议您仔细阅读" Comma-separated values"因此,您更熟悉CSV格式文件的期望。

(注意:此时输入样本哈希被添加到显示密钥实际格式的问题中。)

我将让您弄清楚如何合并CSV,但请冥想:

cop_log = { 'A1' => 'val1', 'B1' => 'val2', 'C1' => 'val3', 'D1' => 'val4', 'E1' => 'val5', 'F1' => 'val6', 'G1' => 'val7', 'H1' => 'val8', 'I1' => 'val9', 'J1' => 'val10', 'K1' => 'val11', 'A2' => 'val12', 'B2' => 'val13', 'C2' => 'val14', 'D2' => 'val15', 'E2' => 'val16', 'F2' => 'val17', 'G2' => 'val18', 'H2' => 'val19', 'I2' => 'val20', 'J2' => 'val21', 'K2' => 'val22'}
cop_log.values.each_slice(11) do |slice|
  puts slice.join(',')
end

# >> val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11
# >> val12,val13,val14,val15,val16,val17,val18,val19,val20,val21,val22

您需要依靠CSV类来创建CSV文件;格式并不像看起来那么简单。

这是我如何编写代码的第一步:

require 'csv'

cop_log = { 'A1' => 'val1', 'B1' => 'val2', 'C1' => 'val3', 'D1' => 'val4', 'E1' => 'val5', 'F1' => 'val6', 'G1' => 'val7', 'H1' => 'val8', 'I1' => 'val9', 'J1' => 'val10', 'K1' => 'val11', 'A2' => 'val12', 'B2' => 'val13', 'C2' => 'val14', 'D2' => 'val15', 'E2' => 'val16', 'F2' => 'val17', 'G2' => 'val18', 'H2' => 'val19', 'I2' => 'val20', 'J2' => 'val21', 'K2' => 'val22'}

job_number = 1
pm_lookup = [0, 1]

CSV.open('./foo.csv', 'w') do |csv|
  cop_log.group_by{ |k, v| k[1] }.values.each do |row|
    csv << [ job_number, pm_lookup[job_number], *row.map{ |k, v| v } ]
  end
end

运行后,foo.csv包含:

1,1,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11
1,1,val12,val13,val14,val15,val16,val17,val18,val19,val20,val21,val22

我们不知道您的预期输出是什么,因为您没有告诉我们,但您可以使用该代码来解决问题。

这是对数据预处理的细分:

cop_log.group_by{ |k, v| k[1] } # => {"1"=>[["A1", "val1"], ["B1", "val2"], ["C1", "val3"], ["D1", "val4"], ["E1", "val5"], ["F1", "val6"], ["G1", "val7"], ["H1", "val8"], ["I1", "val9"], ["J1", "val10"], ["K1", "val11"]], "2"=>[["A2", "val12"], ["B2", "val13"], ["C2", "val14"], ["D2", "val15"], ["E2", "val16"], ["F2", "val17"], ["G2", "val18"], ["H2", "val19"], ["I2", "val20"], ["J2", "val21"], ["K2", "val22"]]}
       .values # => [[["A1", "val1"], ["B1", "val2"], ["C1", "val3"], ["D1", "val4"], ["E1", "val5"], ["F1", "val6"], ["G1", "val7"], ["H1", "val8"], ["I1", "val9"], ["J1", "val10"], ["K1", "val11"]], [["A2", "val12"], ["B2", "val13"], ["C2", "val14"], ["D2", "val15"], ["E2", "val16"], ["F2", "val17"], ["G2", "val18"], ["H2", "val19"], ["I2", "val20"], ["J2", "val21"], ["K2", "val22"]]]

在上面的代码中,我确保输入符合预期的顺序,在这种情况下,我按单位数行进行分组。更强大的代码将使用\d+而不是1,并且还会排序以强制执行适当的顺序。

每当您将数据从一种格式压缩到另一种格式以供日后重用时,这一点非常重要。虽然当前的Rubies保证哈希将保持其插入顺序,但是由于旧版本的Ruby没有这样做,所以它不是一个好的做法,并且您将代码移植到的其他语言可能无法保持顺序。相反,总是采取防御性的方案,确保您能够返回一致的结果。当你发现以前的尝试不够时,你将在多大程度上做到这一点。编程很有趣。

最后,只要您的代码感到尴尬或没有时间进行备份并查看您正在做的事情。

答案 1 :(得分:0)

你不能这样做吗?

CSV.open("path/to/file.csv", "wb") do |csv|
    cop_log.each do |key, value|
        if key.include?('A')
            csv << [ job_number, pm_lookup[job_number], value ]
        elsif key.include?('K') || key.include?('B') || key.include?('C') || key.include?('D') ||
            key.include?('E') || key.include?('F') || key.include?('G') ||
            key.include?('H') || key.include?('I') || key.include?('J')
            csv << [ value ]
      end
    end
end

答案 2 :(得分:0)

def write_csv(cop_log, io = $stdout)
  cop_log.each do |key, value|
    if key.include?('K')
      io.print "#{value}\n"
    elsif key.include?('A')
      io.print "#{job_number},#{pm_lookup[job_number]},#{value},"
    elsif key.include?('B') || key.include?('C') || key.include?('D') ||
          key.include?('E') || key.include?('F') || key.include?('G') ||
          key.include?('H') || key.include?('I') || key.include?('J')
      io.print "#{value},"
    end
  end
end

然后

File.open('path/to/file.csv', 'w') do |f|
  write_csv(cop_log, f)
end

答案 3 :(得分:0)

重新审视代码

    CSV.open("test.csv", "ab") do |csv|
      b = {}
      check_num = 0
      cop_log.each do |key, value|
        num = key.gsub(/[^\d]/, '').to_i
        next if num < 8 ||
                key.include?('L') || key.include?('M') || key.include?('N') ||
                key.include?('O') || key.include?('P') || key.include?('Q') ||
                key.include?('R') || key.include?('S') || key.include?('T') ||
                key.include?('U') || key.include?('V')
        a = { key => value }
        b.merge!(a)
      end # end of each loop
      i = 8
      while ((b.length / 9) - 7) > i do
        csv << [ job_number, pm_lookup[job_number], b["A#{i}"], b["B#{i}"],
                b["C#{i}"], b["D#{i}"], b["E#{i}"], b["F#{i}"], b["G#{i}"],
                b["H#{i}"], b["I#{i}"], b["J#{i}"], b["K#{i}"] ]
        i += 1
      end
    end # end of CSV.open