Standard patterns for arbitrary array constructors

I often find myself doing something like

M = Matrix{Float64}(undef, m, n)
for i ∈ 1:m, j ∈ 1:n
    # do some stuff which is too long for a list comprehension
end

it would be nice if I could do

Matrix{Float64}(m,n) do (i,j)
    # do some stuff which is too long for list comprehension
end

I have a feeling that this probably already exists, but what is the appropriate function called? I can’t seem to find it. Or does it not exist?

6 Likes

(Note that your loops are in a suboptimal order.)

1 Like

Oh sorry, I constantly get it backwards :blush:

…which is why it would be nice to be abstracted away with the “do” block :wink:

3 Likes

You can always do

f(i, j) = ...
[f(i,j) for i in i:size(x,1), j in 1:size(x, 2)]

But this also works:

julia> map(Iterators.product(1:size(x,1), 1:size(x,2))) do I
           i, j = I
           i + j / 2
       end
2×5 Array{Float64,2}:
 1.5  2.0  2.5  3.0  3.5
 2.5  3.0  3.5  4.0  4.5
1 Like

With respect to the original request for Array(f, i, j) where f is callable: I agree! We’re just starting to enter the brave new world where such a thing is theoretically possible and meaningful.

6 Likes

For the record, I wasn’t necessarily asking for exactly that syntax, but I think it would be nice to have something like this.