'JSON.parse' replaces ':' with '=>' - json

I have a string:
{"name":"hector","time":"1522379137221"}
I want to parse the string into JSON and expect to get:
{"name":"hector","time":"1522379137221"}
I am doing:
require 'json'
JSON.parse
which produces this:
{"name"=>"hector","time"=>"1522379137221"}
Can someone tell me how I can keep :? I don't understand why it adds =>.

After you parse the json data you should see it in the programming language that you are using.
Ruby uses => to separated the key from the value in hash (while json uses :).
So the ruby output is correct and the data is ready for you to manipute in your code. When you convert your hash to json, the json library will convert the => back to :.

JSON does not have symbol class. Hence, nothing in JSON data corresponds to Ruby symbol. Under a trivial conversion from JSON to Ruby like JSON.parse, you cannot have a symbol in the output.

Related

Processing JSON from a .txt file and converting to a DataFrame in Julia

Cross posting from Julia Discourse in case anyone here has any leads.
I’m just looking for some insight into why the below code is returning a dataframe containing just the first line of my json file. If you’d like to try working with the file I’m working with, you can download the aminer_papers_0.zip from the Microsoft Open Academic Graph site, I’m using the first file in that group of files.
using JSON3, DataFrames, CSV
file_name = "path/aminer_papers_0.txt"
json_string = read(file_name, String)
js = JSON3.read(json_string)
df = DataFrame([js])
The resulting DataFrame has just one line, but the column titles are correct, as is the first line. To me the mystery is why the rest isn’t getting processed. I think I can rule out that read() is only reading the first JSON object, because I can index into the resulting object and see many JSON objects:
enter image description here
My first guess was maybe the newline \n was causing escape issues, and tried to use chomp to get rid of them, but couldn’t get it to work.
Anyway - any help would be greatly appreciated!
I think the problem is that the file is in JSON Lines format, and the JSON3 library only returns the first valid JSON value that it finds at the start of a string unless told otherwise.
tl;dr
Call JSON3.read with the keyword argument jsonlines=true.
Why?
By default, JSON3 interprets a string passed to its read function as a single "JSON text", defined by RFC 8259 section 1.3.2:
A JSON text is a serialized value....
(My emphasis on the use of the indefinite singular article "a.") A "JSON value" is defined in section 1.3.3:
A JSON value MUST be an object, array, number, or string, or one of the following three literal names: false, null, true.
A string with multiple JSON values in it is technically multiple "JSON texts." It is up to the parser to determine what part of the string argument you give it is a JSON text, and the authors of JSON3 chose as the default behavior to parse from the start of the string to the end of the first valid JSON value.
In order to get JSON3 to read the string as multiple JSON values, you have to give it the keyword option jsonlines=true, which is documented as:
jsonlines: A Bool indicating that the json_str contains newline delimited JSON strings, which will be read into a JSON3.Array of the JSON values. See jsonlines for reference. [default false]
Example
Take for example this simple string:
two_values = "3.14\n2.72"
Each one of these lines is a valid JSON serialization of a number. However, when passed to JSON3.read, only the first is parsed:
using JSON3
#assert JSON3.read(two_values) == 3.14
Using jsonlines=true, both values are parsed and returned as a JSON3.Array struct:
#assert JSON3.read(two_values, jsonlines=true) == [3.14, 2.72]
Other Packages
The JSON.jl library, which people might use by default given the name, does not implement parsing of JSON Lines strings at all, leaving it up to the caller to properly split the string as needed:
using JSON
JSON.parse(two_values)
# ERROR: Expected end of input
# Line: 1
# Around: ...3.14 2.72...
# ^
A simple way to implement reading multiple values is to use eachline:
#assert [JSON.parse(line) for line in eachline(IOBuffer(two_values))] == [3.14, 2.72]

How to parse JSONB array of strings in Ruby

I found many answers for parsing JSON or JSONB but it seems PostgreSQL has its own way of doing things.
I have a CSV dump from PostgreSQL that I want to parse in Ruby.
A column of the dump was made with array_agg. It is an array of strings. Unfortunately, PostgreSQL decided not to double-quote some values. It may believe they are numbers.
require 'json'
original_names = "[\"1800 Reposado 750ML\",1800Jalisco750ml,\"1800 Tequila Reposado, Jalisco, Mexico (750ml)\"]"
array = JSON.parse original_names
# Raises: 434: unexpected token at 'Jalisco750ml,"...' (JSON::ParserError)
I have tried to add the quotes myself, but it fails because of the other string that contain commas.
array = JSON.parse original_names.gsub(/,([^"|,]+),/, ',"\1",')
# Raises: 434: unexpected token at 'Jalisco", Mexico (750ml)"]' (JSON::ParserError)
I spent an hour trying workarounds and now I believe I need to implement the parser myself. Does anyone have a better way?
"Array_agg in postgres selectively quotes" shows that PostgreSQL's json_agg returns proper JSON, which prevents my issue.

Convert doctrine array to JSON

Is there a way to read a column of doctrine type "simply_array" or "array" in json?
My doctrine database is approached from another api and I want to read data from that api. However there is a column of type doctrine array that I want to convert into JSON.
I am unsure if there is a preferred way of doing this or I need to hack my way around it.
Here is an example of what is stored in the database as a doctrine array:
"a:1:{i:0;a:3:{s:3:\u0022day\u0022;i:5;s:4:\u0022time\u0022;s:7:\u0022morning\u0022;s:12:\u0022availability\u0022;N;}}"
That looks like the format of PHP's serialize() function. And the literal double-quotes in the string have been converted to unicode escape sequences.
You could do the following:
Fetch the serialized string
Fix the \u0022 sequences (replace them with ")
unserialize() it to reproduce the array
Convert the array to JSON with json_encode().

Json : getting the unwanted result

I'm using json plugin to get the response in json.
But I m getting the unwanted result:
Here is what I get:
{"data":"[[\"service\",\"webservices\",\"document\"],[\"validation\",\"adapters\",\"server\"]]","records":25,"recordsTotal":75}
originally the data var in my action class is like this:
[["service","webservices","document"],["validation","adapters","server"]]
but json plugin adds the backslash.
The wanted result is that:
{"data":[["service","webservices","document"],["validation","adapters","server"]],"records":25,"recordsTotal":75}
Is there a way to get the later result ?
Thanks
You're representing the data as a PHP string. " is obviously a reserved character in JSON, so your serialization library is dutifully escaping the quote using /.
If you set up the PHP variable so it's an array of arrays, instead of a string representing an array of arrays, then your JSON serialization will work fine.

Convert JSON to CSV or unstructured text

How might you take JSON output (e.g., from http://www.kinggary.com/tools/todoist-export.php) and strip the names to yield just the values from each pair, as CSV or human-friendly text? Want a more readable, human-editable backup of my friend's data on todoist.com
Your example site generates XML for me, not JSON. In either case I'd probably reach for Ruby:
require 'net/http'
require 'rexml/document'
xml = Net::HTTP.get_response(URI.parse("http://www.kinggary.com/tools/todoist-export.php?completed=incomplete&retrieval=view&submit=Submit&process=true&key=MYKEY")).body
data = REXML::Document.new(xml)
data.elements.each('//task/content') do |e|
puts e.text
end
there's a good discussion of how to do this with Python at How can I convert JSON to CSV?
Can you JSON decode it to an array and just iterate the array for values? A sample of the JSON output would be helpful.
What language? PHP has a json_decode() function that turns the JSON into an object or associative array. You could then loop through the array or get the values from the object to turn it into whatever format you like.