Behavior toJSON(pretty=TRUE) differs from prettify()
For example:
toJSON(1:3, pretty = TRUE)
# [1, 2, 3]
prettify(toJSON(1:3, pretty = TRUE))
# [
# 1,
# 2,
# 3
# ]
Is there way to get prettify to give output like toJSON? The reason I ask is because I want to do something like this:
x <- toJSON(list(a=1:3), pretty = TRUE)
x
# {
# "a": [1, 2, 3]
# }
# x is some json object that already exists by the time we get here
y <- toJSON(list(x = x), pretty=TRUE, json_verbatim=TRUE)
y
# {
# "x": {
# "a": [1, 2, 3]
# }
# }
# prettify generates output that is too verbose
prettify(y, indent = 2)
# {
# "x": {
# "a": [
# 1,
# 2,
# 3
# ]
# }
# }
I would like to get output like this:
{
"x": {
"a": [1, 2, 3]
}
}
Another inconsistency: the default indentation for toJSON(pretty=TRUE) is 2, but for prettify() it's 4.
Yes this is expected. The prettify() function uses libyajl indentation which is what we used initially for pretty = TRUE. However in a later version of jsonlite with some help from yihui we added a custom indentation per R class in each asJSON method.
Therefore we can use spaces to split elements of an atomic vector, but linebreaks for lists:
jsonlite::toJSON(1:3, pretty = TRUE, auto_unbox = TRUE)
# [1, 2, 3]
jsonlite::toJSON(as.list(1:3), pretty = TRUE, auto_unbox = TRUE)
# [
# 1,
# 2,
# 3
# ]
Obviously we cannot see this distinction from the json itself, only if we are serializing R objects. So you would have to parse json and then reserialize it to get the R type indentations...
I'm attempting to convert JSON to an R object, and then back to JSON, but I'm having trouble keeping the output semantically the same as the input.
Here's a function that converts from JSON to an R object, then back to JSON, and allows controlling a couple parameters in the conversion.
prettify2 <- function(x, simplifyVector = TRUE, auto_unbox = TRUE) {
toJSON(
fromJSON(x, simplifyVector = simplifyVector),
auto_unbox = auto_unbox,
pretty = TRUE
)
}
Here's a sample JSON object. Ideally, passing it through prettify2() will result in output that looks just like the input.
xj <- '{
"a": 1,
"b": [1],
"c": [1, 2],
"d": [[1], [2]]
}'
# Output is semantically different from input
prettify2(xj, T, T)
# {
# "a": 1,
# "b": 1,
# "c": [1, 2],
# "d": [
# [1],
# [2]
# ]
# }
# Output is semantically different from input
prettify2(xj, T, F)
# {
# "a": [1],
# "b": [1],
# "c": [1, 2],
# "d": [
# [1],
# [2]
# ]
# }
# Semantically same, but too many newlines. Output is same as prettify(xj,
# indent=2).
prettify2(xj, F, T)
# {
# "a": 1,
# "b": [
# 1
# ],
# "c": [
# 1,
# 2
# ],
# "d": [
# [
# 1
# ],
# [
# 2
# ]
# ]
# }
# Output is semantically different from input
prettify2(xj, F, F)
# {
# "a": [1],
# "b": [
# [1]
# ],
# "c": [
# [1],
# [2]
# ],
# "d": [
# [
# [1]
# ],
# [
# [2]
# ]
# ]
# }
I don't always have control over the input JSON, so the goal is for the prettify2 function to work with any JSON. (It should prettify any JSON without semantically altering the content.)