Skip to content

Commit ea82e8a

Browse files
committed
Array(::MatlabStructArray) converts for class object array
1 parent 9969785 commit ea82e8a

File tree

3 files changed

+72
-41
lines changed

3 files changed

+72
-41
lines changed

src/MAT_types.jl

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,8 @@ module MAT_types
7070
names::Vector{String}
7171
values::Vector{Array{Any,N}}
7272
class::String
73-
function MatlabStructArray(names::Vector{String}, values::Vector{Array{Any,N}}, class::String="") where N
74-
# call MatlabStructArray{N}() to avoid the check
75-
check_struct_array(names, values)
73+
function MatlabStructArray(names::Vector{String}, values::Vector{Array{Any,N}}, class::String=""; check::Bool=true) where N
74+
check && check_struct_array(names, values)
7675
return new{N}(names, values, class)
7776
end
7877
function MatlabStructArray{N}(names::Vector{String}, values::Vector{Array{Any,N}}, class::String="") where N
@@ -91,8 +90,11 @@ module MAT_types
9190
end
9291
end
9392

94-
function MatlabStructArray(names::AbstractVector{<:AbstractString}, values::AbstractArray{<:AbstractArray{T,N}}, class="") where {T,N}
95-
MatlabStructArray{N}(string.(names), Vector{Array{Any,N}}(values), string(class))
93+
function MatlabStructArray(names::AbstractVector{<:AbstractString}, values::AbstractArray{A}, class=""; check::Bool=true) where {N, A<:AbstractArray{T, N} where {T}}
94+
MatlabStructArray(string.(names), Vector{Array{Any,N}}(values), string(class); check=check)
95+
end
96+
function MatlabStructArray(names::Vector{String}, values::AbstractArray{A}, class=""; check::Bool=true) where {N, A<:AbstractArray{T, N} where {T}}
97+
MatlabStructArray(names, Vector{Array{Any,N}}(values), string(class); check=check)
9698
end
9799

98100
# empty array
@@ -187,18 +189,23 @@ module MAT_types
187189
Base.Dict{String, Any}(arr.names .=> arr.values)
188190
end
189191

190-
Base.Array(arr::MatlabStructArray) = Array{Dict{String,Any}}(arr)
191-
function Base.Array{D}(arr::MatlabStructArray{N}) where {T,D<:AbstractDict{T},N}
192+
Base.Array{D}(arr::MatlabStructArray{N}) where {D<:AbstractDict,N} = Array{D,N}(arr)
193+
194+
function Base.Array{D, N}(arr::MatlabStructArray{N}) where {D<:AbstractDict,N}
192195
first_field = first(arr.values)
193196
sz = size(first_field)
194197
result = Array{D, N}(undef, sz)
195198
for idx in eachindex(first_field)
196199
element_values = (v[idx] for v in arr.values)
197-
result[idx] = D(T.(arr.names) .=> element_values)
200+
result[idx] = create_struct(D, arr.names, element_values, arr.class)
198201
end
199202
return result
200203
end
201204

205+
function create_struct(::Type{D}, keys, values, class::String) where {T, D<:AbstractDict{T}}
206+
return D(T.(keys) .=> values)
207+
end
208+
202209
struct StructArrayField{N}
203210
values::Array{Any,N}
204211
end
@@ -256,4 +263,17 @@ module MAT_types
256263
end
257264
end
258265
end
266+
267+
function Base.Array(arr::MatlabStructArray{N}) where N
268+
if isempty(arr.class)
269+
return Array{Dict{String,Any}, N}(arr)
270+
else
271+
return Array{MatlabClassObject, N}(arr)
272+
end
273+
end
274+
275+
function create_struct(::Type{D}, keys, values, class::String) where D<:MatlabClassObject
276+
d = Dict{String, Any}(string.(keys) .=> values)
277+
return MatlabClassObject(d, class)
278+
end
259279
end

test/types.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ using MAT, Test
22

33
@testset "MatlabStructArray" begin
44
d_arr = Dict{String, Any}[
5-
Dict("x"=>[1.0,2.0], SubString("y")=>[3.0,4.0]),
5+
Dict("x"=>[1.0,2.0], SubString("y")=>3.0),
66
Dict("x"=>[5.0,6.0], "y"=>[])
77
]
88
s_arr = MatlabStructArray(d_arr)
@@ -44,10 +44,19 @@ using MAT, Test
4444
# possibility to convert back to dict array via `Array`
4545
s_arr = MatlabStructArray(d_arr)
4646
@test Array(s_arr) == d_arr
47+
d_arr_reshape = reshape(d_arr, 1, 2)
48+
@test Array(MatlabStructArray(d_arr_reshape)) == d_arr_reshape
4749
d_symbol = Array{Dict{Symbol,Any}}(MatlabStructArray(d_arr))
4850
@test d_symbol[2][:x] == d_arr[2]["x"]
4951
@test Array(MatlabStructArray(d_symbol)) == d_arr
5052

53+
# class object array conversion
54+
s_arr = MatlabStructArray(d_arr, "TestClass")
55+
c_arr = Array(s_arr)
56+
@test c_arr isa Array{MatlabClassObject}
57+
@test all(c->c.class=="TestClass", c_arr)
58+
@test MatlabStructArray(c_arr) == s_arr
59+
5160
# test error of unequal structs
5261
wrong_sarr = Dict{String, Any}[
5362
Dict("x"=>[1.0,2.0], "y"=>[3.0,4.0]),

test/write.jl

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -153,35 +153,37 @@ test_write(Dict("adjoint_arr"=>Any[1 2 3;4 5 6;7 8 9]'))
153153
test_write(Dict("reshape_arr"=>reshape(Any[1 2 3;4 5 6;7 8 9]',1,9)))
154154

155155
# test nested struct array - interface via Dict array
156-
sarr = Dict{String, Any}[
157-
Dict("x"=>[1.0,2.0], SubString("y")=>[3.0,4.0]),
158-
Dict("x"=>[5.0,6.0], "y"=>[Dict("a"=>7), Dict("a"=>8)])
159-
]
160-
# we have to test Array size is maintained inside mat files
161-
sarr = reshape(sarr, 1, 2)
162-
matwrite(tmpfile, Dict("s_array" => sarr))
163-
read_sarr = matread(tmpfile)["s_array"]
164-
@test read_sarr isa MatlabStructArray
165-
@test read_sarr["y"][2] isa MatlabStructArray
166-
167-
sarr = Dict{String, Any}[
168-
Dict("x"=>[1.0,2.0], SubString("y")=>[3.0,4.0]),
169-
Dict("x"=>[5.0,6.0], "y"=>[])
170-
]
171-
test_write(Dict("s_array" => MatlabStructArray(sarr)))
172-
173-
empty_sarr = MatlabStructArray(["a", "b", "c"])
174-
test_write(Dict("s_array" => empty_sarr))
175-
176-
# old matlab class object array
177-
carr = MatlabStructArray(["foo"], [[5, "bar"]], "TestClassOld")
178-
test_write(Dict("class_array" => carr))
179-
180-
d = Dict{String,Any}("foo" => 5)
181-
obj = MatlabClassObject(d, "TestClassOld")
182-
test_write(Dict("tc_old" => obj))
183-
184-
carr = [MatlabClassObject(d, "TestClassOld"), MatlabClassObject(d, "TestClassOld")]
185-
matwrite(tmpfile, Dict("class_array" => carr))
186-
carr_read = matread(tmpfile)["class_array"]
187-
@test carr_read == MatlabStructArray(carr)
156+
@testset "MatlabStructArray writing" begin
157+
sarr = Dict{String, Any}[
158+
Dict("x"=>[1.0,2.0], SubString("y")=>3.0),
159+
Dict("x"=>[5.0,6.0], "y"=>[Dict("a"=>7), Dict("a"=>8)])
160+
]
161+
# we have to test Array size is maintained inside mat files
162+
sarr = reshape(sarr, 1, 2)
163+
matwrite(tmpfile, Dict("s_array" => sarr))
164+
read_sarr = matread(tmpfile)["s_array"]
165+
@test read_sarr isa MatlabStructArray
166+
@test read_sarr["y"][2] isa MatlabStructArray
167+
168+
sarr = Dict{String, Any}[
169+
Dict("x"=>[1.0,2.0], SubString("y")=>3.0),
170+
Dict("x"=>[5.0,6.0], "y"=>[])
171+
]
172+
test_write(Dict("s_array" => MatlabStructArray(sarr)))
173+
174+
empty_sarr = MatlabStructArray(["a", "b", "c"])
175+
test_write(Dict("s_array" => empty_sarr))
176+
177+
# old matlab class object array
178+
carr = MatlabStructArray(["foo"], [[5, "bar"]], "TestClassOld")
179+
test_write(Dict("class_array" => carr))
180+
181+
d = Dict{String,Any}("foo" => 5)
182+
obj = MatlabClassObject(d, "TestClassOld")
183+
test_write(Dict("tc_old" => obj))
184+
185+
carr = [MatlabClassObject(d, "TestClassOld"), MatlabClassObject(d, "TestClassOld")]
186+
matwrite(tmpfile, Dict("class_array" => carr))
187+
carr_read = matread(tmpfile)["class_array"]
188+
@test carr_read == MatlabStructArray(carr)
189+
end

0 commit comments

Comments
 (0)