Convert Indexes of Nested Array to Index of Flat List

By Xah Lee. Date: .

Problem Description

Suppose you have a array of dimensions {3,2}:

{{"a", "b"}, {"c", "d"}, {"e", "f"}}

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]