# How to display the indices/element positions of a ragged array?

I have a three-level ragged array like so:

array = {{{a, a, a, a}, {a, a, a, a}, {a, a, a}}, {{a}, {a, a, a,
a}, {a, a, a, a}}, {{a, a}, {a, a, a}, {a, a, a, a}, {a, a, a,
a}}, {{a, a, a, a}, {a, a, a, a}, {a, a}, {a, a, a}}, {{a, a,
a}, {a, a, a, a}, {a, a, a}, {a, a, a, a}}};
Grid[array, Frame -> All]


I want to display the indices of this array by replacing each a element by the 3-digit positions of that element. I also want to preserve the structure of the array i.e. no flattening of the original array should occur. Below is an excerpt of what I want my result to be; notice that each number matches up with the position of the a that was previously in that position, and all the the curly brackets are preserved.

{{{111, 112, 113, 114}, {121, 122, 123, 124}, {131, 132, 133}}, ...}


I tried to use Position[array, a] but I only got back a flattened list of all the positions of a, which makes sense since Position is only supposed to show me the positions of a without preserving the list hierarchy.

Position[array, a]
(* {{1, 1, 1}, {1, 1, 2}, {1, 1, 3}, {1, 1, 4}, {1, 2, 1}, {1, 2, 2}, {1,
2, 3}, {1, 2, 4}, {1, 3, 1}, {1, 3, 2}, {1, 3, 3}, {2, 1, 1}, {2,
2, 1}, {2, 2, 2}, {2, 2, 3}, {2, 2, 4}, {2, 3, 1}, {2, 3, 2}, {2, 3,
3}, {2, 3, 4}, {3, 1, 1}, {3, 1, 2}, {3, 2, 1}, {3, 2, 2}, {3, 2,
3}, {3, 3, 1}, {3, 3, 2}, {3, 3, 3}, {3, 3, 4}, {3, 4, 1}, {3, 4,
2}, {3, 4, 3}, {3, 4, 4}, {4, 1, 1}, {4, 1, 2}, {4, 1, 3}, {4, 1,
4}, {4, 2, 1}, {4, 2, 2}, {4, 2, 3}, {4, 2, 4}, {4, 3, 1}, {4, 3,
2}, {4, 4, 1}, {4, 4, 2}, {4, 4, 3}, {5, 1, 1}, {5, 1, 2}, {5, 1,
3}, {5, 2, 1}, {5, 2, 2}, {5, 2, 3}, {5, 2, 4}, {5, 3, 1}, {5, 3,
2}, {5, 3, 3}, {5, 4, 1}, {5, 4, 2}, {5, 4, 3}, {5, 4, 4}} *)


My question is:

How do I display the indices of a (ragged) array elements--preferably concatenated instead of {_,_,_}--and still keep the list structures intact?

PS: Here are some other things that I've tried which did not work:

1) array /. a -> Position[array, a]

This did not work because each a is replaced by a huge list of all positions of a in the array.

2) array /. array[[i_, j_, k_]] -> 100 i + 10 j + k

This would not work either because apparently Part does not take patterns.

MapIndexed[StringJoin[ToString /@ #2] &, array, {-1}]

• lol that's the quickest I've ever deleted an answer :) – mfvonh Jul 17 '14 at 23:57
• hm yes, I saw "there's 1 new answer", clicked on it and saw your deleted answer! – acl Jul 17 '14 at 23:58
• omg you rock! I want to kiss you right now. – seismatica Jul 18 '14 at 1:00

You can use ReplacePart[] :

ReplacePart[array, x : {_, _, _} :> StringJoin[ToString /@  x]]

• I really wish I could also accept this answer as this is such an intuitive yet elegant approach. – seismatica Jul 19 '14 at 1:10

This may also help

array2 = array;(*To preserve the original matrix*)
p = Position[array2, a];
(array2[[Sequence @@ #]] = StringJoin[ToString /@ #]) & /@ p;
array2

• Thanks so much @Algohi. I was first intrigued by your having pure functions on both sides of the equations but after seeing the full form of your method ((array2[[Sequence @@ #]] = StringJoin[ToString /@ #]) & /@ p // Hold // FullForm), it became clear set the = is a mere Set function that could be mapped to all p. Now I understand why in MMA, "everything is an expression". – seismatica Jul 18 '14 at 1:28
• @seismatica yes you are correct. everything in MMA is an expression. thank you for your comment:) – Algohi Jul 18 '14 at 2:15