1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

jsonからcsvに変換してみる

Last updated at Posted at 2019-09-12

2019-09-13 追記: 逆バージョンもやってみた。


久々に再帰とか使った。


def json_to_csv(src_json_path, out_csv_path)
  data = JSON.parse(IO.read(src_json_path))
  @result = {}
  recursive_parse('', data)

  header = @result.keys.join(",")
  body = @result.values.join(",")

  open(out_csv_path,'w') do |f|
    f.puts(header)
    # 改行を空白に置換
    f.puts(body.gsub("\n", " "))
  end
end

def recursive_parse(chain_key, obj)
  if obj.class == Hash
    obj.each { |k,v| recursive_parse(chain_key + "|" + k.to_s , v )}
  elsif obj.class == Array
    obj.each_with_index { |v, idx| recursive_parse(chain_key + "|[" + idx.to_s + "]", v)}
  else
    @result[chain_key] = obj
  end
end

json_to_csv('./tmp/test_data.json', './tmp/out.csv')

戻す方はなんか長くなったのでクラスにしてしまった。

# frozen_string_literal: true

# reCreate json from csv
class CsvToJson
  require 'json'

  EMPTY_VAR_NAME = '@empty_json_hash'
  COPIED_VAR_NAME = '@copied_json_hash'

  def csv_to_json(src_csv_path, out_json_path)
    @empty_json_hash = {}

    File.open(src_csv_path, 'r') do |f|
      @header = f.gets.chomp
      @bodies = f.each_line.inject([]) { |res, line| res << line.chomp }
    end
    header_to_json_object(@header)

    @bodies.each_with_index do |body, idx|
      @copied_json_hash = @empty_json_hash.dup
      values_into_json_object(@header, body)

      File.open(renamed_path(out_json_path, idx), 'w') do |f|
        f.puts JSON.pretty_generate(@copied_json_hash)
      end
    end
  end

  private

  def renamed_path(path, idx)
    File.dirname(path) + "/#{idx}_" + File.basename(path)
  end

  def header_to_json_object(line)
    object_define_list = line.split(',')
    object_define_list.each { |item| recursive_parse_define_string(item, 0) }
  end

  def make_tree(items, var_name)
    items.inject(var_name) { |res, i| res + (/\[|\]/ =~ i ? i : "[\"#{i}\"]") }
  end

  def suffix(target)
    /\[|\]/ =~ target ? ' = []' : ' = {}'
  end

  def recursive_parse_define_string(item, depth)
    buffer = item.split('|').reject(&:empty?)
    current = make_tree(buffer[0..depth], EMPTY_VAR_NAME)
    next_index = depth + 1

    # element at bottom. so exit this method
    return eval(current + " = ''") if next_index == buffer.length

    eval(current + suffix(buffer[next_index])) unless eval(current)

    recursive_parse_define_string(item, next_index)
  end

  def values_into_json_object(header, body)
    headers = header.split(',')
    bodies = body.split(',')

    headers.each_with_index do |item, idx|
      buffer = item.split('|').reject(&:empty?)
      eval(make_tree(buffer, COPIED_VAR_NAME) + ' = ' + "\"#{bodies[idx]}\"")
    end
  end
end

CsvToJson.new.csv_to_json('./tmp/out.csv', './tmp/out.json')

1
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?