# JSON3: ERROR: MethodError: no method matching Array{Int64,2}(::Array{Int64,1})

**URL:** <https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457>\
**Category:** General Usage\
**Tags:** json\
**Created:** [December 8, 2020, 1:28pm UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457 "2020-12-08T13:28:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![sz1992](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sz1992/32/19219_2.png) [@sz1992](https://discourse.julialang.org/u/sz1992)\
**Post date:** [December 8, 2020, 1:28pm UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457/1 "2020-12-08T13:28:51Z")

</div>

Hi,  
i need some help with JSON3. If I add Arrays into my custom structure, I get error on JSON3.read.  
MWE:

```julia
Base.@kwdef mutable struct MyStruct3
    name::String = ""
    par1::Int = 10
    par2::Int32 = 32
    par3::Array{Int,2} = [0 0 0]
end

JSON3.StructTypes.StructType(::Type{MyStruct3}) = JSON3.StructTypes.Mutable()
ms=MyStruct3()
JSON3.write(ms)
write(tempdir() * "/p1.json",JSON3.write(ms))
js=read(tempdir() * "/p1.json")
JSON3.read(js,MyStruct3)

```

and error:

```julia
ERROR: MethodError: no method matching Array{Int64,2}(::Array{Int64,1})
Closest candidates are:
  Array{Int64,2}(::AbstractArray{S,N}) where {T, N, S} at array.jl:562
  Array{Int64,2}(::UndefInitializer, ::Int64, ::Int64) where T at boot.jl:408
  Array{Int64,2}(::UndefInitializer, ::Int64...) where {T, N} at boot.jl:412

 
Stacktrace:
 [1] construct(::Type{T} where T, ::Array{Int64,1}; kw::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at C:\Users\znidar\.julia\packages\StructTypes\CpLmq\src\StructTypes.jl:301
 [2] construct(::Type{T} where T, ::Array{Int64,1}) at C:\Users\znidar\.julia\packages\StructTypes\CpLmq\src\StructTypes.jl:301
 [3] #readarray#29 at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:207 [inlined]
 [4] readarray at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:187 [inlined]
 [5] #read#27 at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:183 [inlined]
 [6] read at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:183 [inlined]
 [7] #read#26 at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:182 [inlined]
 [8] read at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:182 [inlined]
 [9] #_#36 at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:373 [inlined]
 [10] MutableClosure at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:372 [inlined]
 [11] applyfield! at C:\Users\znidar\.julia\packages\StructTypes\CpLmq\src\StructTypes.jl:666 [inlined]
 [12] #read!#39 at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:438 [inlined]
 [13] read! at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:389 [inlined]
 [14] #read#37 at C:\Users\znidar\.julia\packages\JSON3\hC8pW\src\structs.jl:380 [inlined]

```

Any suggestion?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 8, 2020, 1:37pm UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457/2 "2020-12-08T13:37:27Z")

</div>

I think JSON3 does not support multi-dimensional arrays. You have to read them as unidimensional and then reshape.

---

<div class="post-metadata">

**Author:** ![sz1992](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sz1992/32/19219_2.png) [@sz1992](https://discourse.julialang.org/u/sz1992)\
**Post date:** [December 8, 2020, 2:06pm UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457/3 "2020-12-08T14:06:07Z")

</div>

Defining the struct:

```julia
Base.@kwdef mutable struct MyStruct4
    name::String = ""
    par1::Int = 10
    par2::Int32 = 32
    par3::Array{Int,2} = [0 0 0;1 2 3]
end

```

returns Dict as:

```julia
JSON3.Object{Array{UInt8,1},Array{UInt64,1}} with 4 entries:
  :name => ""
  :par1 => 10
  :par2 => 32
  :par3 => [0, 1, 0, 2, 0, 3]

```

par3 is already flattened and read into structure returns error.

Are there any plans to add support for multi-dims arrays in written JSON (like JSONTables) and/or automatic reshaping in JSON3.read as structure is known - parameter to JSON3.read?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 8, 2020, 4:09pm UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457/4 "2020-12-08T16:09:03Z")

</div>

I asked that some time ago, and I don’t think so.

> [@\[ANN\] JSON3.jl - Yet another JSON package for Julia](https://discourse.julialang.org/t/ann-json3-jl-yet-another-json-package-for-julia/25625/20):
>
> There currently isn’t a builtin/clean way to transform multidimensional arrays into json and back out. There’s an open issue for it, but it needs some thinking to the right API.

In your specific case, since your structure is mutable, you can directly reshape that field with `obj.par3 = reshape(obj.par3,2,3)`. My issue was worse, because my structure was immutable, and I had to define another structure just to read the json file with the same fields, but with a linear array, and then initialize the actual data structure from this temporary structure with linearized arrays.

By the way, my solution ended up not being very elegant, and someone can point to a better solution which might be useful to you as well. What I did is to define four macros, one with the fields before the matrix, two with either the matrix or the linearized form (a vector) and a third with the fields after that matrix. Something like:

```julia
macro Results_Start()
  ex = quote
    data1
    data2 
  end; esc(ex)
end
macro Results_Matrix()
  ex = quote
    atoms :: Array{Float64,2}
  end; esc(ex)
end
macro Results_Vector()
  ex = quote
    atoms :: Vector{Float64}
  end; esc(ex)
end
macro Results_End()
  ex = quote
    data4
    data5
  end; esc(ex)
end

```

Then I define two structs, with these macros, which share all the fields except the matrix or vector one:

```julia
struct Result
  @Result_Start()
  @Result_Matrix()
  @Result_End()
end

mutable struct MutableResult
  @Result_Start()
  @Result_ector()
  @Result_End()
end

```

The `MutableResult` struct is only used for reading the JSON file, reshape that matrix and initialize the immutable struct with

```julia
  return Result([getfield(R,field) for field in fieldnames(Result)]...)

```

All this seems pretty ugly, so I guess there are better solutions.

---

<div class="post-metadata">

**Author:** ![sz1992](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sz1992/32/19219_2.png) [@sz1992](https://discourse.julialang.org/u/sz1992)\
**Post date:** [December 9, 2020, 7:25am UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457/5 "2020-12-09T07:25:33Z")

</div>

@lmiq thanks for sharing you workaround.

I did a small comparation to JSON:

```julia
Base.@kwdef mutable struct MyStruct4
    name::String = ""
    par1::Int = 10
    par2::Int32 = 32
    par3::Array{Int,2} = [0 0 0;1 2 3]
end

```

```julia
julia> JSON.json(ms)
"{\"name\":\"\",\"par1\":10,\"par2\":32,\"par3\":[[0,1],[0,2],[0,3]]}"

julia> JSON3.write(ms)
"{\"name\":\"\",\"par1\":10,\"par2\":32,\"par3\":[0,1,0,2,0,3]}"

```

One can see that JSON deals with Array in a good way. However JSON3 flatten it. Parsing back should be done with JSON using Unmarshall.jl. The reason I checked JSON3 is that JSON3 works well with missing and redundant keys, what is not case with JSON.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 9, 2020, 10:14am UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457/6 "2020-12-09T10:14:16Z")

</div>

Does JSON read the array correctly afterwards?

I had the impression that JSON was considered deprecated in favor of JSON3 at this point.

---

<div class="post-metadata">

**Author:** ![sz1992](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sz1992/32/19219_2.png) [@sz1992](https://discourse.julialang.org/u/sz1992)\
**Post date:** [December 9, 2020, 12:07pm UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457/7 "2020-12-09T12:07:26Z")

</div>

My current usage to write/read my struct (it just configuration for an algorithm therefore performance is not relevant) in JSON format is as follows:

```julia
using JSON, Unmarshal
ms=MyStruct4()
json_data=JSON.json(ms) 
##write to file, read back
ms_data=JSON.parse(json_data)
ms=Unmarshal.unmarshal(MyStruct4, ms_data)

```

```julia
julia> using JSON, Unmarshal

julia> ms=MyStruct4()
MyStruct4("", 10, 32, [0 0 0; 1 2 3])

julia> json_data=JSON.json(ms)
"{\"name\":\"\",\"par1\":10,\"par2\":32,\"par3\":[[0,1],[0,2],[0,3]]}"

julia> ms_data=JSON.parse(json_data)
Dict{String,Any} with 4 entries:
  "name" => ""
  "par1" => 10
  "par3" => Any[Any[0, 1], Any[0, 2], Any[0, 3]]
  "par2" => 32

julia> ms=Unmarshal.unmarshal(MyStruct4, ms_data)
MyStruct4("", 10, 32, [0 0 0; 1 2 3])

julia>

```

The reason to try JSON3 was two fold: depreciation and handling missing or redundant keys in JSON file (more reliable). However no support for arrays is a drawback.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 9, 2020, 12:28pm UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457/8 "2020-12-09T12:28:35Z")

</div>

Thank you. But we still need a temporary struct to read the data, it seems. In that case it is not that different from reading and reshaping afterwards. Ideally the `parse` or `read` functions of JSON would directly read the data into the array of the appropriate shape (although I understand that this would only be possible if the exact shape of the data is known in advance and defined in the structure - I see that this is not a very common scenario).

---

<div class="post-metadata">

**Author:** ![sz1992](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sz1992/32/19219_2.png) [@sz1992](https://discourse.julialang.org/u/sz1992)\
**Post date:** [December 9, 2020, 12:41pm UTC](https://discourse.julialang.org/t/json3-error-methoderror-no-method-matching-array-int64-2-array-int64-1/51457/9 "2020-12-09T12:41:48Z")

</div>

JSON + Unmarshal:

- deals with Array
- deals with redundand keys in JSON data
- supports missing data in a limited way: field type has to be Union with Nothing/nullable/Missing
- does not support if type has default value assigned

JSON3:

- do not deals with Array
- deals with redundand keys in JSON data
- supports missing data: default value is assigned if it is defined in field

A CR in JSON3 to cover Arrays would be best approach.
