我已经处理了一个输入文件并创建了以下格式的数据结构
final = [ {:server=>"new_US_dof1_new"},
{:name=>"OLAUS51", :data=>{"HAL"=>"6.93817139", "CCN_RESP"=>".035400391", "PA_RESP"=>".032287598", "PE_RESP"=>".000610352"}},
{:name=>"OLAUS10", :data=>{"HAL"=>"52.7266846", "CFG_RESP"=>"15.9489746"}},
{:name=>"IdofQA03", :data=>{"PA_RESP"=>".096374512"}},
{:name=>"QEMDB", :data=>{"HAL"=>"22.2698975", "PA_RESP"=>"11.7857666", "CCN_RESP"=>".229125977", "PE_RESP"=>".007202148"}},
{:name=>"OLAUS64", :data=>{"CCN_RESP"=>".757202148"}},
{:name=>"IISCR70", :data=>{}},
{:name=>"IQDV500", :data=>{}},
{:name=>"OLAUS80", :data=>{"PA_RESP"=>"10.5393066", "HAL"=>"4.73620605", "CCN_RESP"=>".023864746", "PE_RESP"=>".003723145", "OPENREPORTS"=>".001708984", "REPORT_RESP"=>".001281738"}},
{:server=>"new_US_dof2_new"},
{:name=>"IBDVHAL", :data=>{"HAL"=>"1.81048584", "FM_RESP"=>".001098633"}},
{:name=>"DEVSITEP", :data=>{"HAL"=>".088012695", "PE_RESP"=>".000610352"}},
{:name=>"OLAUS87", :data=>{"CFG_RESP"=>"1.57061768", "HAL"=>".47253418", "PA_RESP"=>".011962891", "PE_RESP"=>".007202148"}}]
我想出了以下代码来处理并获得上述格式
final = []
count = -1
output = File.open("input.txt").read
output.each_line do |line|
line.strip!
next if line.empty?
next if line.include?('rows') || line.include?('occ')
next if ['-','='].include? line[0]
parts = line.split ' '
if parts.size == 1 and line.start_with?('new_')
final[count += 1] = {server: line, data: {}}
next
elsif parts.size == 1 and parts = /^(?!.*new_).*$/
final[count += 1] = {name: line, data: {}}
next
end
parts.each_cons(2) do |key, value|
final[count][:data][key] = value
end
end
p = Axlsx::Package.new
p.workbook.add_worksheet(:name => "Basic") do |sheet|
style1 = sheet.styles.add_style(:bg_color => "EF0920", :fg_color => "FFFFFF", b:true, :sz => 14, :alignment => { :horizontal=> :center })
style2 = sheet.styles.add_style(:bg_color => "00FF00", :fg_color => "FFFFFF", b:true, :sz => 12, :alignment => { :horizontal=> :center })
sheet.add_row ["VM", "NAME", "DATA", "SIZE"], :style => style1
final.each do |val|
if val.key?(:server)
sheet.add_row [ val[:server], val[:name], "", "" ] , :style =>[style2, nil]
next
elsif val.key?(:name)
sheet.add_row [ "", val[:name], "", "" ]
val[:data].each do |k, v|
sheet << ["", "", k, v]
end
end
end
end
我正在尝试将数据格式化为以下结构(预期)
但是我的代码抛出类似这样的输出
因此,我将打印值修改为
val[:data].each do |k, v|
sheet << [val[:server], val[:name], k, v]
end
我使用if循环进行了字符串验证,以匹配以'new_'开头的行,并将服务器和名称值推送到新数组,从而在每次迭代中仅打印唯一值,但没有任何效果。在这里设置标志会有所帮助吗?
我并没有完全知道如何打印服务器和命名值的逻辑,就像我上面提到的那样。 (预期部分)
此外,棘手的事情是在每个“名称”部分保留一个空白行-就像OLAUS51和OLAUS10之间的空行一样,其他名称值也是如此 在每个服务器值之间-new_US_dof1_new和new_US_dof2_new。
任何帮助解决此问题的方法都将大有帮助,非常感谢!
答案 0 :(得分:1)
为什么不呢?根据我过去的回答:
final.each_with_object([]) do |val, line|
# when key :server exist set server's name as first element for line
# otherwise set empty value to create a blank cell at position 1
line << (val.key?(:server) ? val[:server] : '') if line.empty?
# when key :server exist, in the current hash no needed data
next if val.key?(:server)
# at this place line look like [server_name/'']
# so, when no key :server, in each base hash present keys :name and :data
line << val[:name]
# line => [server_name, name] for new server
# line => ['', name] for new properties for the same server
# for {name: 'some name', data: {}}
sheet.add_row [*line, '', ''], :style =>[style2, nil] if val[:data].empty?
val[:data].each do |k, v|
# add values from data hash
line << k << v
# push line to the sheet
# first iteration for val[:data]
# line => [server_name/'', name, data_key, data_value]
# iteration 2+
# line => ['', '', data_key, data_value]
sheet.add_row line.clone, :style =>[style2, nil]
# array line from each_with_object can't be replaced but can be cleaned
line.clear
# line => []
# push two blank values
line << '' << ''
# line => ['', '']
# that line's data will be used for the current loop
end
# add a blank line after block :data
sheet.add_row []
# line => ['', '']
# cleaning a line for next hash
line.clear
# line => []
end