# How to replace the element in list of list by its ordering index

I have a list of list: res={{9, 1, 5}, {3, 6, 12}} I want to change it to res={{5, 1, 3}, {2, 4, 6}} by following their ordering index such that 1 to 1, 3 to 2, 5 to 3, 6 to 4, 9 to 5, and 12 to 6. How can I achieve this?

res={{9, 1, 5}, {3, 6, 12}};

ArrayReshape[InversePermutation[Ordering[Flatten[res]]],
Dimensions[res]]
(* {{5,1,3},{2,4,6}} *)

• Similarly, alternatively, res /. Thread[Flatten[res] -> InversePermutation@Ordering@Flatten@res]. Commented Oct 19, 2022 at 18:30
• Maybe post it as a separate answer? If I compare the two, I think your solution supports more general shapes, mine only supports arrays. And they behave differently when res contains duplicates. Commented Oct 19, 2022 at 18:35
• Sounds good. Will do. Commented Oct 19, 2022 at 18:39

A method that works for lists with arbitrary structure:

ClearAll[ranks]
ranks = InternalCopyListStructure[#, Ordering @ Ordering @ Flatten @ #] &;


Examples:

ranks @ {{9, 1, 5}, {3, 6, 12}}

 {{5, 1, 3}, {2, 4, 6}}

ranks @ {{9, 1, 5}, 3, {3, 1}, {3, {{{{6}}}, 12}}}

 {{8, 1, 6}, 3, {4, 2}, {5, {{{{7}}}, 9}}}


Building off of user293787's answer, but possibly more general because it works for ragged arrays as well:

res /. Thread[Flatten[res] -> InversePermutation@Ordering@Flatten@res]

• I think this should be the accepted answer ;) Commented Oct 19, 2022 at 18:40
copy = InternalCopyListStructure;

rank = StatisticsLibraryGetDataRankings;

a = {{9, 1, 5}, {3, 6, 12}};

copy[a, rank @ Flatten @ a]


{{5, 1, 3}, {2, 4, 6}}