# Changing an element inside array of arrays

Hello!
Can anyone explain a strange result of changing one element inside an array of arrays?

julia> b1=fill(zeros(4),4)
4-element Array{Array{Float64,1},1}:
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]

julia> b1[1][1]=100.0
100.0

julia> b1
4-element Array{Array{Float64,1},1}:
[100.0, 0.0, 0.0, 0.0]
[100.0, 0.0, 0.0, 0.0]
[100.0, 0.0, 0.0, 0.0]
[100.0, 0.0, 0.0, 0.0]

What you actually do is:

``````julia> z=zeros(4)
4-element Array{Float64,1}:
0.0
0.0
0.0
0.0

julia> b1=[z,z,z,z]
4-element Array{Array{Float64,1},1}:
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
``````

Now doing

``````julia> z[1]=100.0
100.0

julia> b1
4-element Array{Array{Float64,1},1}:
[100.0, 0.0, 0.0, 0.0]
[100.0, 0.0, 0.0, 0.0]
[100.0, 0.0, 0.0, 0.0]
[100.0, 0.0, 0.0, 0.0]
``````

Is not so surprising anymore.

What you want, I would create with:

``````julia> b2 = [ zeros(4) for i in 1:4 ]
4-element Array{Array{Float64,1},1}:
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]

julia> b2[1][1]=100.0
100.0

julia> b2
4-element Array{Array{Float64,1},1}:
[100.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
``````

but there are probably more elegant ways.

Thank you for the decision.
Yet it’s still unclear how the equal arrays can produce different results.

julia> b1=fill(zeros(4),4)
4-element Array{Array{Float64,1},1}:
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]

julia> b2=[zeros(4) for i in 1:4]
4-element Array{Array{Float64,1},1}:
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0]

julia> isequal(b1,b2)
true

``````julia> b1==b2
true

julia> b1===b2
false
``````
1 Like

`isequal` (or also `==` FWIW) only compares the value. It ignores many other properties of the object being compared.

As examples.

``````julia> a = [1, 2, 3]; b = 1:3
1:3

julia> isequal(a, b)
true

julia> push!(a, 1)
4-element Array{Int64,1}:
1
2
3
1

julia> push!(b, 1)
ERROR: MethodError: no method matching resize!(::UnitRange{Int64}, ::Int64)
Closest candidates are:
resize!(::Array{T,1} where T, ::Integer) at array.jl:1016
resize!(::BitArray{1}, ::Integer) at bitarray.jl:773
Stacktrace:
[1] _append!(::UnitRange{Int64}, ::Base.HasLength, ::Tuple{Int64}) at ./array.jl:920
[2] append!(::UnitRange{Int64}, ::Tuple{Int64}) at ./array.jl:914
[3] push!(::UnitRange{Int64}, ::Int64) at ./array.jl:915
[4] top-level scope at REPL[4]:1

julia> isequal(0x1, 1)
true

julia> -0x1
0xff

julia> -1
-1
``````

OTOH, `is` (or `===`) checks if the two objects are the same one. There is not a general way to compare if the two objects “behaves identically” since that’s not really a well defined concept anyway…

1 Like

In the `fill` case there is only one array referenced 4 times. Equality relates to the values in the object, not the memory layout.

Thanks a lot for the explanations.
To check it I can compare elements inside both arrays.

julia> b1[1]===b1[2]
true

julia> b2[1]===b2[2]
false

1 Like