Looks like a case for PositionIndex
:
ClearAll[positionIdx]ClearAll[toPositions]
positionIdxtoPositions = PositionIndex[#] /@ Range[Max@#] /. _Missing -> {} &;
Examples:
positionIdxtoPositions @ {4, 1, 1}
{{2, 3}, {}, {}, {1}}
positionIdxtoPositions @ {5, 2, 3, 2, 5, 3, 5, 5}
{{}, {2, 4}, {3, 6}, {}, {1, 5, 7, 8}}
To recover the input list from positions:
ClearAll[fromPositions]
fromPositions = Values @* KeySort @*
KeyValueMap[Sequence @@ Thread[List /@ # -> First@#2] &]
@* KeyDrop[{{}}] @* PositionIndex;
Examples:
fromPositions@{{2, 3}, {}, {}, {1}}
{4, 1, 1}
fromPositions@{{}, {2, 4}, {3, 6}, {}, {1, 5, 7, 8}}
{5, 2, 3, 2, 5, 3, 5, 5}
SeedRandom[1]
list = RandomChoice[Range@6, 10]
{5, 3, 5, 1, 2, 1, 1, 3, 1, 1}
toPositions@list
{{4, 6, 7, 9, 10}, {5}, {2, 8}, {}, {1, 3}}
fromPositions @ %
{5, 3, 5, 1, 2, 1, 1, 3, 1, 1}
SeedRandom[1]
lists = RandomChoice[Range@7, {100, 20}];
AllTrue[fromPositions@toPositions@# == # &] @ lists
True