JSON в CSV, пропуская одни столбцы и изменяя порядок других — Ruby

У меня есть рабочий сценарий, который прекрасно преобразует файлы 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

Как я могу отредактировать этот скрипт, чтобы:

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

До сих пор все, что я пробовал, полностью ломало сценарий — с чего лучше всего начать вносить эти изменения?

Отфильтруйте ключи json, чтобы удалить определенные столбцы. И используйте отсортированный массив, чтобы сохранить порядок вывода. Что вы пробовали?

knh190 08.04.2019 04:56

@knh190 knh190 Я в основном работал с заголовками, но мой фильтр каждый раз разбивает массив. Я попытался использовать оператор switch для «h», чтобы отфильтровать столбцы, которые мне не нужны после «headings.map do |h|» - было бы лучше сосредоточиться на ключах json перед заголовками?

Kobius 08.04.2019 05:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
369
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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", "something": {"sub_key": "Wuhu"} }

Это здорово! Работает отлично, я также настроил это, чтобы теперь включать только указанные заголовки, а не удалять определенные заголовки.

Kobius 08.04.2019 20:21

Другие вопросы по теме