# Pushing to an array which is an element of another array (Modifying an array in an array)

**URL:** <https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179>\
**Category:** Performance\
**Created:** [August 2, 2022, 4:52pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179 "2022-08-02T16:52:34Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jonas208](https://avatars.discourse-cdn.com/v4/letter/j/85f322/32.png) [@Jonas208](https://discourse.julialang.org/u/Jonas208)\
**Post date:** [August 2, 2022, 4:52pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/1 "2022-08-02T16:52:34Z")

</div>

Imagine the following situation:  
I create an array with a fixed size and every element in this array is another array.  
In a loop, I want to _push tuples to one array of the outer array_.  
So I want to modify one array which is an element of the outer array.  
The following code example is a heavily simplified snippet from my code. Therefor, the code snippet doesn’t do anything useful.

```julia
# fill an array full of emty arrays
outer_array = fill([], dim1, dim2, dim3, ...)
# modifiying arrays of outer array (I choosed three for-loops instead of eachindex() because it is more similar to my original code)
for z in 1:dim1, for y in 1:dim2, for x in 1:dim3
       # current solution to modify array
       sub_arr = copy(outer_array[z, y, x])
       push!(sub_array, (*content in tuple*))
       outer_array[z, y, x] = sub_array
end

```

This solution is terrible slow, so there must be some better solutions, maybe without copying the array??

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 2, 2022, 5:09pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/2 "2022-08-02T17:09:49Z")

</div>

just push directly to `outer_array[z, y, x]`?

(if you do `sub_array = outer_array[z, y, x]`, without the copy, that should work to, the assignment won’t copy the sub array).

In parallel, you should not use `[]`, untyped, it is better if you, knowning the type of the tuples, use `typeof(tuples)[]`, to have a concretely typed array.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 2, 2022, 5:46pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/3 "2022-08-02T17:46:04Z")

</div>

> [@Jonas208](#):
>
> `outer_array = fill([], dim1, dim2, dim3, ...)`

Also, don’t use `fill` here. It will create an array of references to the same single array. So pushing to one of them, will be visible everywhere.

Use an array comprehension instead.

And, as @lmiq says, `[]` are not good here. Whenever you see `[]` in your code, it’s a bad sign.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 2, 2022, 5:50pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/4 "2022-08-02T17:50:58Z")

</div>

> [@lmiq](#):
>
> (if you do `sub_array = outer_array[z, y, x]`, without the copy, that should work to

Indeed, it is also unnecessary to reassign the subarray. Just replace this

> [@Jonas208](#):
>
> ```julia
> sub_arr = copy(outer_array[z, y, x])
> push!(sub_array, (*content in tuple*))
> outer_array[z, y, x] = sub_array
> 
> ```

with this single line

```julia
push!(outer_array[z, y, x], (*content in tuple*))

```

---

<div class="post-metadata">

**Author:** ![Jonas208](https://avatars.discourse-cdn.com/v4/letter/j/85f322/32.png) [@Jonas208](https://discourse.julialang.org/u/Jonas208)\
**Post date:** [August 2, 2022, 6:16pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/5 "2022-08-02T18:16:58Z")

</div>

Thank you (@Imiq , @DNF ) for your quick responses.  
I think using `fill` was the main problem.  
My current solution:

```julia
outer_array = [[] for _ in 1:dim1, _ in 1:dim2, _ in 1:dim3]
for z in 1:dim1, for y in 1:dim2, for x in 1:dim3
       push!(outer_array[z, y, x], (*content in tuple*))
end

```

That works, but I don’t have type annotations yet. So how can I get rid of `[]` in the array comprehension and how can I assign the type Tuple to `[]`?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 2, 2022, 6:22pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/6 "2022-08-02T18:22:38Z")

</div>

> [@Jonas208](#):
>
> `outer_array[z, y, x]`

I’m not sure if this has any significant impact here, but as Julia is column-major, the inner/fastest changing loop variable should correspond to `z`, and it seems to be `x` in your example. Try swapping the variables in the for loops.

---

<div class="post-metadata">

**Author:** ![Jonas208](https://avatars.discourse-cdn.com/v4/letter/j/85f322/32.png) [@Jonas208](https://discourse.julialang.org/u/Jonas208)\
**Post date:** [August 2, 2022, 6:37pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/7 "2022-08-02T18:37:05Z")

</div>

Thank you, too. I already heard about Julia’s column-major order, but I never really paid attention to it.  
So do you mean something like should be faster?

```julia
for x in 1:dim3, for y in 1:dim2, for x in 1:dim1
       push!(outer_array[z, y, x], (*content in tuple*))
end

```

Do I have to change something else to work column-oriented or is not only the order of the loops important?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 2, 2022, 6:39pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/8 "2022-08-02T18:39:41Z")

</div>

You need to correct the typo (it should be `z` in the inner loop) and AFAIK, yes, that is the recommended loop order for Julia multidimensional arrays.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 2, 2022, 6:51pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/9 "2022-08-02T18:51:37Z")

</div>

> [@Jonas208](#):
>
> So how can I get rid of `[]` in the array comprehension and how can I assign the type Tuple to `[]`?

What is the type of `(*content in tuple*)`? Prepend that to `[]`. For example, if it’s `Tuple{Float64, Int}`, you write

```julia
outer_array = [Tuple{Float64, Int}[] for _ in 1:dim1, _ in 1:dim2, _ in 1:dim3]

```

> [@Jonas208](#):
>
> Thank you, too. I already heard about Julia’s column-major order,

Elements that are consecutive in the first dimension will be consecutive in memory. But in this case, the elements are references to other arrays, located elsewhere (and _those_ element will be consecutive), so in this case it is unlikely to make difference. Can’t hurt, though.

---

<div class="post-metadata">

**Author:** ![Jonas208](https://avatars.discourse-cdn.com/v4/letter/j/85f322/32.png) [@Jonas208](https://discourse.julialang.org/u/Jonas208)\
**Post date:** [August 3, 2022, 8:15pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/10 "2022-08-03T20:15:58Z")

</div>

Thank you all for your answers. Now, the real code in my project works aswell.  
The main problem was that I used fill (post #3).

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [August 3, 2022, 10:12pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/11 "2022-08-03T22:12:07Z")

</div>

> [@Jonas208](#):
>
> ```julia
> for z in 1:dim1, for y in 1:dim2, for x in 1:dim3
> push!(outer_array[z, y, x], (*content in tuple*))
> end
> 
> ```

An easier way to write this loop is

```julia
for zyx in eachindex(IndexCartesian(),outer_array)
       z,y,x = Tuple(zyx) # only need this if you want to extract the individual indices
       push!(outer_array[zyx], (*content in tuple*)) # could also index with [z,y,x]
end

```

This will work even if you change the number of dimensions in your array (except the `z,y,x = Tuple(i)` part won’t) or if you use an array with unusual indexing. This will also use an index order that is good for most standard Julia arrays.

EDIT: thanks to the commenter below for pointing out that I had originally written `CartesianIndex()` in my suggestion rather than the correct `IndexCartesian()`.

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [August 3, 2022, 10:45pm UTC](https://discourse.julialang.org/t/pushing-to-an-array-which-is-an-element-of-another-array-modifying-an-array-in-an-array/85179/12 "2022-08-03T22:45:41Z")

</div>

I think you meant `eachindex(IndexCartesian(), outer_array)` rather than `eachindex(CartesianIndex(), outer_array)`
