Convert JSON to TSV and TSV to JSON with Ruby

Introduction

Thing you want to do

Convert TSV files to JSON format and JSON to TSV files

environment

Ruby 2.6.5 Mac OS 10.15.5

Samples used in this article

[{"name":"john","gender":"m","age":"18"},
 {"name":"paul","gender":"m","age":"20"},
 {"name":"alice","gender":"f","age":"15"},
 {"name":"dabid","gender":"m","age":"17"},
 {"name":"jasmin","gender":"f","age":"17"}]
Name	gender	age
john	m	18
paul	m	20
alice	f	15
dabid	m	17
jasmin	f	17

How to convert from JSON to TSV

 require "json" # Described to handle JSON

 File.open("meibo.json") do |json| #Open JSON file
   File.open("meibo.txt", "w") do |txt| #Open the output TSV file
 array = JSON.load (json) #Load JSON
 column = ["name", "gender", "age"] #header
 txt.puts (column.join ("\ t")) # Insert header
     array.each do |line| #Put each element of the JSON array on each line of the TSV file
      attr = [line["name"],line["gender"],line["age"]]
      txt.puts(attr.join("\t"))
    end
  end
end

First, open the JSON file. Also open the output destination TSV file in write mode. Next, read the JSON file. As shown below, JSON reads a JSON file with JSON.load ([File object]) and returns it as an array with a hash as an element.

require "json"

 File.open("meibo.json") do |json|
  array = JSON.load(json)
  p array
end

=>
[{"name"=>"john", "gender"=>"m", "age"=>"18"}, {"name"=>"paul", "gender"=>"m", "age"=>"20"}, {"name"=>"alice", "gender"=>"f", "age"=>"15"}, {"name"=>"dabid", "gender"=>"m", "age"=>"17"}, {"name"=>"jasmin", "gender"=>"f", "age"=>"17"}]

It is an image that the returned array is turned by the ʻeach method and each hash is made line by line in TSV. As a technique to put in each line of TSV, the value of each hash fetched by ʻeach is fetched by directly specifying the key, and they are put back in the array once. Then, use the join method to join the arrays by tab delimiter and insert the string into each line of the TSV file.

The output result is as follows.

name	gender	age
john	m	18
paul	m	20
alice	f	15
dabid	m	17
jasmin	f	17

Where I was addicted

At first, as shown below, when the array after JSON.load was sent to ʻeach` processing, it was stored in TSV in the order of the values of each object. ** The order of the JSON members (key and value set) does not matter **.

That is, {" name ":" john "," gender ":" m "," age ":" 18 "} and {" name ":" john "," age ":" 18 "," gender " : "m"} is indistinguishable.

Therefore, this time it happens that there is no problem if you convert to TSV in the order of the JSON members, but if the JSON is in a different order, it will be strange when converted to TSV. It was.

So, it's troublesome, but once you take out the value by specifying the hash key, put it in the array in the order of the columns, and then put it in the TSV, it is sure.

require "json" 

 File.open("meibo.json") do |json|
   File.open("meibo.txt", "w") do |txt|
    array = JSON.load(json)
    column = ["name","gender","age"]
    txt.puts(column.join("\t"))
     array.each do |line|
 txt.puts (line.values.join ("\ t")) Enter into TSV according to the order of values of each object of #JSON
    end
  end
end

How to convert from TSV to JSON

require "json"
require "csv"

hash_ary = []

 File.open("meibo.json","w") do |json|
   CSV.foreach("meibo.txt",col_sep: "\t", headers: true) do |line|
    h = {name: line[0], gender: line[1], age: line[2]}
    hash_ary << h
  end
 Use JSON.dump (hash_ary, json) #to_json
end

First, prepare a file for writing JSON in write mode.

The TSV file is a CSV class that uses the foreach method to convert each line into a hash. Put the converted hash in the array (here, hash_ary), and after all the lines have been inserted, convert the hash to JSON with JSON.dump and write it to the file.

The output result is as follows.

[{"name":"john","gender":"m","age":"18"},{"name":"paul","gender":"m","age":"20"},{"name":"alice","gender":"f","age":"15"},{"name":"dabid","gender":"m","age":"17"},{"name":"jasmin","gender":"f","age":"17"}]

Where I was addicted

require "json"
require "csv"

hash_ary = []

 File.open("meibo.json","w") do |json|
   CSV.foreach("meibo.txt",col_sep: "\t", headers: true) do |line|
    h = {name: line[0], gender: line[1], age: line[2]}
    hash_ary << h.to_json
  end
  json << hash_ary
end

At first, it was written as above, but if you do it like this. ..

["{\"name\":\"john\",\"gender\":\"m\",\"age\":\"18\"}", "{\"name\":\"paul\",\"gender\":\"m\",\"age\":\"20\"}", "{\"name\":\"alice\",\"gender\":\"f\",\"age\":\"15\"}", "{\"name\":\"dabid\",\"gender\":\"m\",\"age\":\"17\"}", "{\"name\":\"jasmin\",\"gender\":\"f\",\"age\":\"17\"}"]

As you can see, \ was inserted before " and it could not be converted successfully.

The to_json method returns a JSON-formatted ** string **, so using JSON.dump instead of this solved the problem.

Recommended Posts

Convert JSON to TSV and TSV to JSON with Ruby
Convert ruby object to JSON format
[Ruby] How to convert from lowercase to uppercase and from uppercase to lowercase
Try to link Ruby and Java with Dapr
Convert Java enum enums and JSON to and from Jackson
Convert to Ruby Leet string
Converting TSV files to CSV files (with BOM) in Ruby
How to handle TSV files and CSV files in Ruby
[Java] Convert JSON to Java and Java to JSON-How to use GSON and Jackson-
Compared processing time to convert Apache Arrow and JSON to Yosegi
How to deal with different versions of rbenv and Ruby
Convert Markdown to HTML with flexmark-java
How to convert LocalDate and Timestamp
Convert line feed code to html line feed tag with Thymeleaf and output
[Android] Convert Map to JSON using GSON in Kotlin and Java
With ruby ● × Game and Othello (basic review)
Convert C language to JavaScript with Emscripten
Convert numbers to Roman numerals in Ruby
[Easy] How to upgrade Ruby and bundler
Sample to create PDF from Excel with Ruby
Introduction to Ruby 2
[Ruby] How to convert CSV file to Yaml (Yml)
[Ruby] Arguments with keywords and default values of arguments
I implemented Ruby with Ruby (and C) (I played with builtin)
[Ruby] How to use gsub method and sub method
Convert a string to a character-by-character array with swift
JSON with Java and Jackson Part 2 XSS measures
[Ruby] "Reference to object" and "Contents of variable"
[Swift] Convert ByteArray and HexString to each other
Create jupyter notebook with Docker and run ruby
Diffed with JSON
Convert Json to List <T> as it is
Try to get redmine API key with ruby
Solving with Ruby and Crystal AtCoder ABC 129 D
AtCoder ABC127 D hash to solve with Ruby 2.7.1
How to build API with GraphQL and Rails
Moved to anyenv! (Manage rbenv and nodenv with anyenv)
Ruby and Gem
I tried to convert JavaBean and XML with Jackson formatter XML in this era
[Java] Convert and import file values with OpenCSV
Convert JSON and YAML in Java (using Jackson and SnakeYAML)
<java> Read Zip file and convert directly to string
Convert large XLSX files to CSV with Apache POI
I tried to read and output CSV with Outsystems
Solving with Ruby and Java AtCoder ABC129 D 2D array
[Ruby] Exclude and replace specific patterns with regular expressions
Solving with Ruby, Perl and Java AtCoder ABC 128 C
How to make LINE messaging function made with Ruby
[Java] Convert character strings to uppercase / lowercase (AOJ⑨-swap uppercase and lowercase)
Convert the array of errors.full_messages to characters and output
I started MySQL 5.7 with docker-compose and tried to connect
[Ruby] I made a crawler with anemone and nokogiri.
[Java] Refer to and set private variables with reflection
How to serialize and deserialize LocalDateTime type with GSON
Feel the basic type and reference type easily with ruby 2
I want to transition screens with kotlin and java!
How to convert A to a and a to A using AND and OR in Java
Install rbenv with apt on ubuntu and put ruby
How to use RealSense with ubuntu 20.04 and ROS Noetic
How to install Gradle and Kotlin with SDKMAN (Mac)
[Ruby] How to get the tens place and the ones place