JSON3.jl
JSON3.jl copied to clipboard
higher rank arrays should appear as nested lists
For example, see the behavior of JSON.jl
julia> A = [1 0
0 1]
2×2 Array{Int64,2}:
1 0
0 1
julia> JSON.json(A)
"[[1,0],[0,1]]"
julia> A = rand(2,2,2)
2×2×2 Array{Float64,3}:
[:, :, 1] =
0.293369 0.187349
0.0572265 0.719968
[:, :, 2] =
0.521351 0.454227
0.546091 0.773648
julia> JSON.json(A)
"[[[0.2933693401153792,0.057226458190521745],[0.18734882624283,0.7199679429526]],[[0.52135120453497,0.54609145253139],[0.4542265690601863,0.7736478960773061]]]"
It would also be nice to at least have the option for there to be an inverse of this. That is, a function which reads in a nested JSON and automatically constructs an AbstractArray of the appropriate rank. For me personally, this would be a great default behavior in cases where all elements are a common type, but I can see how this would be controversial.
It might also be worth considering doing column-wise instead of row-wise ordering because that would match Julia's memory layout, however this might clash with conventions that exist outside of Julia.
I agree with this proposal and serialization of multidimensional array is convenient for scientific computing if HDF5 is not suitable for the scenario. Instead of nested arrays, a flattened array for data and another array for shape can be used. For example, for a matrix
A = [1 2; 3 4]
We can write it as:
{
"shape" : [2, 2],
"data" : [1, 2, 3, 4]
}
shape parameter can be used to reshape the data to multidimensional array.
I commented on a newer issue here, but by using Tables.matrix, Tables.table, and the JSONTables.jl package, it's actually pretty easy to convert a Matrix to json output as object of arrays or array of objects, and then read that back in as a matrix.
Coming back to this; I think it'd be possible to special-case higher-rank Arrays when reading/writing. Writing would be a little easier, because I think there are ways to iterate over high-rank arrays so you get the nested slices. Reading might be trickier though, because we need to detect the rank initially.
That said, I think it might even be easier/less breaking to only support reading in the explicit case: i.e. when you do something like JSON3.read(json, Matrix{Float64}). Then we can just have a specialized read method for Matrix or other higher-rank Arrays that will expect the nested arrays to read from. Anybody feel like taking a stab at this?
I actually prefer the idea of @metab0t to serialize the data in a linear index style and also store the shape. It seems like serializing arrays as nested lists would make it hard to distinguish them from nested vectors.