# Using views to mutate parts of arrays

I’m playing around with Julia 1.0.3 and getting confused. I have written a function that mutates an array. I want to use this function to mutate a part of a larger array. I can’t wrap my head around why some things work and some don’t. Here are examples:

``````function f!(x)
for i in eachindex(x)
x[i] = i
end
end

x = randn(2, 3)
f!(view(x, :, :))
x
``````

These work:

``````f!(view(x, :, :))
f!(view(x, 1, :))
f!(view(x, :, axes(x, 2)))
f!(view(x, 1, 1:2))
``````

But these does not work:

``````f!(view(x, 1:2, 1:2))
f!(view(x, 1, 1))
f!(view(x, 1:2, 1:3))
f!(view(x, axes(x, 1), axes(x, 2)))
f!(view(x, axes(x, 1), :))
``````

The problem is that `eachindex` may return a `CartesianIndex` that can’t be stored back into an array of floats

``````> x = randn(2, 3)
> eachindex(view(x,1:2,1:2))
2×2 CartesianIndices{2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}:
CartesianIndex(1, 1)  CartesianIndex(1, 2)
CartesianIndex(2, 1)  CartesianIndex(2, 2)
``````

If `x` is an array of `Any`, your mutating function works as is

``````> x = Array{Any}(undef,2,3)
> f!(view(x,1:2,1:2))
> x
2×3 Array{Any,2}:
CartesianIndex(1, 1)  CartesianIndex(1, 2)  #undef
CartesianIndex(2, 1)  CartesianIndex(2, 2)  #undef
``````

You can explicitly ask for linear (integer) indexes using `eachindex(IndexLinear(),x)` (these would probably be a bit less efficient for arbitrary views, since the iteration logic is more complicated).

1 Like

Of course, how silly of me.
Thank you!