'Implementing N-dim arrays in Erlang
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.
Solution 1:[1]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | TnTech |