Convert Indexes of Nested Array to Index of Flat List
Problem Description
Suppose you have a array of dimensions {3,2}:
{{"a", "b"}, {"c", "d"}, {"e", "f"}}
- The index for element a is {1,1},
- The index for element b is {1,2},
- The index for element c is {2,1},
- The index for element d is {2,2},
- Etc.
We start index counting at 1.
now, if you flatten the array, then the index for each element is just 1, 2, 3, etc. (we start index counting at 1.)
The problem, is to write a function, that takes 2 arguments.
posToFlatIndex[dimensionsSpec, elementIndex]
where dimensionsSpec is the shape of the array, and
elementIndex is a index of a particular element,
and return the corresponding index for the flattened array.
In our example,
posToFlatIndex[{3, 2}, {1,1}]
returns 1,
posToFlatIndex[{3, 2}, {2,2}]
returns 4.
For example, here is a matrix of dimension {3, 2, 4}. Each element shows its index.
dm = {3, 2, 4}
matrix = Array[p, dm]
{ { {p[1, 1, 1], p[1, 1, 2], p[1, 1, 3], p[1, 1, 4]}, {p[1, 2, 1], p[1, 2, 2], p[1, 2, 3], p[1, 2, 4]}}, { {p[2, 1, 1], p[2, 1, 2], p[2, 1, 3], p[2, 1, 4]}, {p[2, 2, 1], p[2, 2, 2], p[2, 2, 3], p[2, 2, 4]}}, { {p[3, 1, 1], p[3, 1, 2], p[3, 1, 3], p[3, 1, 4]}, {p[3, 2, 1], p[3, 2, 2], p[3, 2, 3], p[3, 2, 4]}}}
posToFlatIndex[{3, 2, 4}, {3, 2, 3}]
return
23
This is useful, when you want to generate graphics directly using
GraphicsComplex
data structure.
Solution
posToFlatIndex = Function[{dimen,pos},Module[ {dp = Length@dimen }, Sum[ (pos[[n]]-1) * Product[dimen[[m]] , {m , n+1, dp}] , {n,1,dp-1}] + pos[[dp]] ] ]; (* test *) dm = {3,2,4}; matrix = Array[p,dm]; MapIndexed[ f[#, posToFlatIndex[dm,#], #2]&, Flatten@matrix]