JSON в CSV, пропуская определенные столбцы и переупорядочивая другие - Ruby - PullRequest
0 голосов
/ 08 апреля 2019

У меня есть рабочий сценарий, который прекрасно преобразует JSON-файлы в CSV-файлы, однако я пытаюсь отредактировать сценарий, чтобы внести некоторые изменения в CSV-файл перед сохранением, в настоящее время безуспешно.

Вот мой текущий скрипт преобразования:

require 'csv'
require 'json'
require 'set'

def get_recursive_keys(hash, nested_key=nil)
  hash.each_with_object([]) do |(k,v),keys|
    k = "#{nested_key}.#{k}" unless nested_key.nil?
      if v.is_a? Hash
      keys.concat(get_recursive_keys(v, k))
    else
      keys << k
    end
  end
end

json = JSON.parse(File.open(ARGV[0]).read)
headings = Set.new
json.each do |hash|
  headings.merge(get_recursive_keys(hash))
end

headings = headings.to_a
CSV.open(ARGV[0] + '.csv', 'w') do |csv|
  csv << headings
  json.each do |hash|
    row = headings.map do |h|
      v = hash.dig(*h.split('.'))
      v.is_a?(Array) ? v.join(',') : v
    end
    csv << row
  end
end

Который я запускаю с этой командой:

for file in directory/*; do ruby json-to-csv.rb "$file"; done

Как мне отредактировать этот скрипт на:

  • Удалить столбцы с определенными заголовками, такими как «Score» и «Original_name»
  • (изменить порядок оставшихся столбцов в алфавитном порядке слева направо) - если возможно?

Пока все, что я пробовал, полностью нарушает сценарий - где лучше всего начать вносить эти изменения?

1 Ответ

1 голос
/ 08 апреля 2019

Вот код, который работает:

require 'csv'
require 'json'
require 'set'

def get_recursive_keys(hash, nested_key=nil)
  hash.each_with_object([]) do |(k,v),keys|
    # Col filter
    next if ["score", "original_name"].include? k
    k = "#{nested_key}.#{k}" unless nested_key.nil?
    if v.is_a? Hash
      keys.concat(get_recursive_keys(v, k))
    else
      keys << k
    end
  end
end

json = JSON.parse(File.open(ARGV[0]).read)
headings = Set.new
headings = get_recursive_keys(json)

headings = headings.to_a
# Header sorting
headings = headings.sort { |a, b| a <=> b }


CSV.open(ARGV[0] + '.csv', 'w') do |csv|
  csv << headings
  row = headings.map do |h|
    v = (h.split('.').length > 1) ? json.dig(*h.split('.')) : h
    v.is_a?(Array) ? v.join(',') : v
  end
  csv << row
end

Я тестировал эту маленькую строку json: {"score": "12", "name": "Obi", "original_name": "Wan Kenobi", "кое-что": {"sub_key": "Wuhu"} }

...