Gickle
Gickle

Reputation: 141

How to change specific field in custom type arrays' element?

Here is the deal. I made a custom type in Julia lang:

type points
  x::Float64
  y::Float64
  z::Float64
end

And also made an array of this type:

S = Array(ponits,1,Int(N))

So now I want to change field x of i's (e.g. i=3) array element to, for example, 4.28. But when I do this:

S[3].x = 4.28

it changes ALL array S. Thus I have array S with all elements having x-filed equals 4.28. I read Julia's documentations and did not find anything about this. How does it work in Julia?

Thanks in advance.

P.S. Oh, since I already made this thread. How to make a zero-element of custom type? For exaplme, zero of points type would be something like (0,0,0).

Upvotes: 0

Views: 130

Answers (1)

Reza Afzalan
Reza Afzalan

Reputation: 5746

If you have an array of references to a same object, and try to mutate one of them you will get that result, e.g. if using fill() function to fill an array with an object, may leads to the following issue:

julia> s=Vector{Points}(3)
3-element Array{Points,1}:
 #undef
 #undef
 #undef
julia> fill!(s,Points(NaN,NaN,NaN))
3-element Array{Points,1}:
 Points(NaN,NaN,NaN)
 Points(NaN,NaN,NaN)
 Points(NaN,NaN,NaN)
julia> s[1].x=1
1.0

julia> s
3-element Array{Points,1}:
 Points(1.0,NaN,NaN)
 Points(1.0,NaN,NaN)
 Points(1.0,NaN,NaN)

To avoid this kind of issue use the array-comprehension to fill it:

s=[Points(NaN,NaN,NaN) for i=1:3]

But what I see from your sample code is that:

The Points datatype do not have a custom constructor and besides that, s array have not been initialized.

julia> s = Array(Points,1,4)
1x4 Array{points,2}:
 #undef  #undef  #undef  #undef

so if you try to mutate on element you will get an error:

julia> s[1].x
ERROR: UndefRefError: access to undefined reference
 in getindex at array.jl:282

one solution with minimal changes is to use Points default constructor like this:

s[1]=Points(NaN,NaN,NaN)

After that you will be able to mutate element of s , s[1].x=4.28

Secondly to have zero of Points type, you should add zero(::Points) method:

julia> import Base.zero

julia> zero(::Points)=Points(0,0,0)
zero (generic function with 14 methods)

julia> zero(Points(1,2,3))
Points(0.0,0.0,0.0)

Tip: Using an 1XN array to handle an Array of N elements is not the best choice, Refer, use Vector{Type}(N) instead.

Upvotes: 5

Related Questions