# Appending to an array along dimension n

I am trying to write a function that fills rows along the `i`th dimension `n` many times. Let’s call this function `fill_n_times`. If the function takes parameters

``````fill_n_times(M, n, fill_elem; dim = 1)
``````

Then my expected output is

``````julia> rand(Int8, 2, 2)
2×2 Array{Int8,2}:
28  23
-47  54

julia> fill_n_times(A, 2, 3, dim = 1) # repeat the value 3 twice along the first dimension
4×2 Array{Int64,2}:
28  23
-47  54
3   3
3   3
``````

The closest I have to a function like this is as follows, but it doesn’t quite do what I want (I keep getting a dimension mismatch):

``````function fill_n_times(M, n, fill_elem; dim = 1)
return cat(M, collect(Iterators.repeated(fill(fill_elem, size(M, dim)), n))..., dims = dim)
end

# OR

function fill_n_times(M, n, fill_elem; dim = 1)
return cat(M, fill(fill_elem, (n, size(M, dim))), dims = dim)
end
``````

Regarding the latter function, I have to change `(n, size(M, dim))` to `(size(M, dim), n)` for `dim = 2` (and that’s only for two-dimensional arrays!).

How can I generalise this? I have not very much experience working with higher dimensions.

I think you should work out the size of the new block first – it’s the same as that of `A`, except along the indicated dimension, where it has size `n`.

``````julia> function fill_n_times(A::AbstractArray{<:Any,N}, n::Integer, el; dims::Integer=1) where {N}
sz = ntuple(d -> d==dims ? n : size(A,d), max(N,dims))
cat(A, fill(el, sz); dims=dims)
end;

julia> A = rand(Int8, 2, 2);

julia> fill_n_times(A, 2, 101; dims = 1)
4×2 Matrix{Int64}:
61   -7
-31  -36
101  101
101  101

julia> fill_n_times(A, 2, 44; dims = 4)
2×2×1×3 Array{Int64, 4}:
[:, :, 1, 1] =
61   -7
-31  -36

[:, :, 1, 2] =
44  44
44  44

[:, :, 1, 3] =
44  44
44  44
``````
1 Like

@mcabbott ahh, thanks so much. That is a clever solution I probably wouldn’t have thought of…