Ruby can parse JSON, transform the data, and generate CSV text in one small flow.

data transform Data exchange often means reading one format and writing another deterministic format.

Data Transform

minimum
data_transform.rb
Replay: real traced execution (multi-file project)
require "csv"
require "json"

minimum = 80
json_text = '[{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}]'
records = JSON.parse(json_text)

selected = records.select { |record| record["score"] >= minimum }
names = selected.map { |record| record["name"] }
names_text = names.join("/")

csv_text = CSV.generate do |csv|
  csv << ["name"]
  names.each { |name| csv << [name] }
end

csv_line_count = csv_text.lines.count

puts "minimum=#{minimum}"
puts "count=#{names.length}"
puts "names=#{names_text}"
puts "csv_lines=#{csv_line_count}"
require "csv"
require "json"

minimum = 70
json_text = '[{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}]'
records = JSON.parse(json_text)

selected = records.select { |record| record["score"] >= minimum }
names = selected.map { |record| record["name"] }
names_text = names.join("/")

csv_text = CSV.generate do |csv|
  csv << ["name"]
  names.each { |name| csv << [name] }
end

csv_line_count = csv_text.lines.count

puts "minimum=#{minimum}"
puts "count=#{names.length}"
puts "names=#{names_text}"
puts "csv_lines=#{csv_line_count}"
require "csv"
require "json"

minimum = 90
json_text = '[{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}]'
records = JSON.parse(json_text)

selected = records.select { |record| record["score"] >= minimum }
names = selected.map { |record| record["name"] }
names_text = names.join("/")

csv_text = CSV.generate do |csv|
  csv << ["name"]
  names.each { |name| csv << [name] }
end

csv_line_count = csv_text.lines.count

puts "minimum=#{minimum}"
puts "count=#{names.length}"
puts "names=#{names_text}"
puts "csv_lines=#{csv_line_count}"
  1. minimum ← 80, json_text ← [{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}]

    1require "csv"2require "json"34minimum→ 80 = 80  #@minimum=70, 905json_text→ [{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}] = '[{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}]'6records→ [{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}] = JSON.parse(json_text)[{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}]78selected→ [{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}] = records[{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}].select { |record| record["score"] >= minimum }9names→ ["Ada", "Matz"] = selected[{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}].map { |record| record["name"] }10names_text→ Ada/Matz = names.join("/")Ada/Matz1112csv_text = CSV.generate do |csv|13  csv << ["name"]14  names.each { |name| csv << [name] }15end
  2. csv_text ← name\nAda\nMatz\n

    12csv_text→ name\nAda\nMatz\n = CSV.generate do |csv#<CSV io_type:StringIO encoding:US-ASCII lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">|13  csv << ["name"]14  names["Ada", "Matz"].each { |name| csv << [name] }15end
  3. csv_line_count ← 3

    17csv_line_count→ 3 = csv_text.lines.count31819puts "minimum=#{minimum80}"20puts "count=#{names.length2}"21puts "names=#{names_textAda/Matz}"22puts "csv_lines=#{csv_line_count3}"
    outputminimum=80
    count=2
    names=Ada/Matz
    csv_lines=3
  1. minimum ← 70, json_text ← [{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}]

    1require "csv"2require "json"34minimum→ 70 = 705json_text→ [{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}] = '[{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}]'6records→ [{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}] = JSON.parse(json_text)[{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}]78selected→ [{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}] = records[{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}].select { |record| record["score"] >= minimum }9names→ ["Ada", "Matz", "Grace"] = selected[{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}].map { |record| record["name"] }10names_text→ Ada/Matz/Grace = names.join("/")Ada/Matz/Grace1112csv_text = CSV.generate do |csv|13  csv << ["name"]14  names.each { |name| csv << [name] }15end
  2. csv_text ← name\nAda\nMatz\nGrace\n

    12csv_text→ name\nAda\nMatz\nGrace\n = CSV.generate do |csv#<CSV io_type:StringIO encoding:US-ASCII lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">|13  csv << ["name"]14  names["Ada", "Matz", "Grace"].each { |name| csv << [name] }15end
  3. csv_line_count ← 4

    17csv_line_count→ 4 = csv_text.lines.count41819puts "minimum=#{minimum70}"20puts "count=#{names.length3}"21puts "names=#{names_textAda/Matz/Grace}"22puts "csv_lines=#{csv_line_count4}"
    outputminimum=70
    count=3
    names=Ada/Matz/Grace
    csv_lines=4
  1. minimum ← 90, json_text ← [{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}]

    1require "csv"2require "json"34minimum→ 90 = 905json_text→ [{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}] = '[{"name":"Ada","score":90},{"name":"Matz","score":85},{"name":"Grace","score":70}]'6records→ [{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}] = JSON.parse(json_text)[{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}]78selected→ [{"name"=>"Ada", "score"=>90}] = records[{"name"=>"Ada", "score"=>90}, {"name"=>"Matz", "score"=>85}, {"name"=>"Grace", "score"=>70}].select { |record| record["score"] >= minimum }9names→ ["Ada"] = selected[{"name"=>"Ada", "score"=>90}].map { |record| record["name"] }10names_text→ Ada = names.join("/")Ada1112csv_text = CSV.generate do |csv|13  csv << ["name"]14  names.each { |name| csv << [name] }15end
  2. csv_text ← name\nAda\n

    12csv_text→ name\nAda\n = CSV.generate do |csv#<CSV io_type:StringIO encoding:US-ASCII lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">|13  csv << ["name"]14  names["Ada"].each { |name| csv << [name] }15end
  3. csv_line_count ← 2

    17csv_line_count→ 2 = csv_text.lines.count21819puts "minimum=#{minimum90}"20puts "count=#{names.length1}"21puts "names=#{names_textAda}"22puts "csv_lines=#{csv_line_count2}"
    outputminimum=90
    count=1
    names=Ada
    csv_lines=2