Data Container like in Matlab Structure Arrays

Hello everybody,

I am master student in simulations in germany. I am newcomer from Matlab because the performance of Matlab is too low for my discretization in the additive manufactaring.

Julia is really nice, but I have a problem about the data container. I know structs and etc.

I used Structure Arrays in Matlab that was a easy way to manage the big data.
Please, watch the picture.

Its similar to structs but not the same in two points.
I can’t hand over single variabels to a struct and the initialization is not the know way.

For example:

struct Person

age::Int64
Marks::Vector{Float64}

end

x = Person(4,zeros(2,))
# x = Person(4) is not possible

#What I need is above
# First Person
Person[1].age  = 4;
Person[1].Marks = zeros(2,);
# Second Person
Person[2].age = 5;
Person[2].Marks = ones(2,);

Thanks for every help community.

Hello and welcome to the community!

If you want to change the fields of a struct after it has been created, it must be declared mutable, i.e.,

mutable struct Person
    age::Int64
    Marks::Vector{Float64}
end

you can also set default values for the fields like so:

Base.@kwdef mutable struct Person
    age::Int64 = 0
    Marks::Vector{Float64} = Float64[]
end

after this you can create a vector of persons

persons = [Person() for _ in 1:2]
persons[1].age  = 4;
persons[1].Marks = zeros(2,);
# Second Person
persons[2].age = 5;
persons[2].Marks = ones(2,);
1 Like

You may also have a look at
https://github.com/JuliaArrays/StructArrays.jl

Thanks for you help. Have a nice day :).

1 Like

For performance reasons (if the solution above does not perform fast enough), you may want to use Immutable structs indeed, and in that case you need to “replace” the person in each position of your vector of persons.

julia> struct Person
           age::Int64
           Marks::Vector{Float64}
       end

julia> persons = [Person(4,zeros(4)), Person(5,zeros(4))];

julia> persons[1] = Person(6,persons[1].Marks) # replace first person using the previous fields

julia> persons
2-element Vector{Person}:
 Person(6, [0.0, 0.0, 0.0, 0.0])
 Person(5, [0.0, 0.0, 0.0, 0.0])

Note that the elements of the Marks are mutable in both cases (being the Person struct mutable or not).

That of course is generally true, but in this scenario if one uses StructArrays, it may be possible to use an immutable structure. For example

julia> using StructArrays

julia> struct Person
           age::Int64
           Marks::Vector{Float64}
       end

julia> persons = StructArray([Person(4, zeros(4)), Person(5, zeros(4))])
2-element StructArray(::Vector{Int64}, ::Vector{Vector{Float64}}) with eltype Person:
 Person(4, [0.0, 0.0, 0.0, 0.0])
 Person(5, [0.0, 0.0, 0.0, 0.0])

julia> persons.age[1] = 10;

julia> persons
2-element StructArray(::Vector{Int64}, ::Vector{Vector{Float64}}) with eltype Person:
 Person(10, [0.0, 0.0, 0.0, 0.0])
 Person(5, [0.0, 0.0, 0.0, 0.0])

The trick here is that you are editing directly the component vector that holds the ages of all persons. (The structures themselves are generated on the fly when indexing into the StructArray.)

1 Like