Implementing N-dim arrays in Erlang

Viewed 46

I have an Erlang project requiring generating a nested list of array indices. Perhaps using arrays: would be a quick solution, but I would like to see how this is done without that module.

If one knows the number of dimensions of an array, creating a nested list of array indices can be done in one line eg.

array2Dim(M,N) -> [[[X,Y] || X <- lists:seq(1,N)] || Y <- lists:seq(1,M)].

I've been struggling to implement a function, say arrayNDim/1 that will take a list [D1,D2,..., Dn] of unknown length containing dimensions to generate the indices of the D1 x D2 x...,Dn array.

I have thought about spawning processes as a 'gear train' to produce the structure but I suspect the solution might be much simpler.

1 Answers

The most obvious solution is using a Cartesian product of lists [1,...,D1], [1..,D2],...,[1...Dn]. As in the question Cartesian products are easy with list comprehensions but only straightforward when the number of factors is known. What I ended up doing was writing a generalised outer product function outer/3 that takes two lists and a product function as arguments. By taking something like fun(X,Y) -> [X,Y] end as the product and with a judicious use of lists:flatten/2 we almost have our Cartesian product. I say almost as the result is not a tree of coordinates but rather a flattened list [[1,..,1],[1,..,2],...] of coordinates. For my purposed this was sufficient.

Other interesting solutions (I have yet to fully implement these as exercises) are: using a chain of processes each manifesting a counter, as in the question; and making full use of the functional nature of Erlang by generating functions from templates in something akin to nested for loops. Both are interesting in their own way.

Related