Faster position-based duplicate removal in a ragged array?
Another solution using memoization:
keepFirst[lst_List] := Module[{isFirst},
isFirst[elem_, col_] := (isFirst[elem, col] = False; True);
Pick[lst, MapIndexed[isFirst[#1, Last[#2]] &, lst, {2}]]
]
This is faster for the given array:
keepFirstK7[lst_List] :=
Delete[lst,
Flatten[(GatherBy[Position[lst, #], Last] & /@
DeleteDuplicates[Flatten@lst])[[All, All, 2 ;;]], 2]]
keepFirstK7@rArray
$\ $ {{4, 2, 1, 0}, {2}, {0, 0, 3, 3, 3}, {}, {3, 4}}
Another approach
keepFirstK[lst_List] := Block[{sowFirst},
sowFirst[int_, count_] := (sowFirst[int, count] = int; Sow[int]);
Flatten /@
Part[Reap[Block[{cnt = 1}, sowFirst[#, cnt++] & /@ #]] & /@ lst,
All, 2]]
By using Flatten[..., 1]
instead of Flatten /@ ...
one would get rid of the empty lists.
Or simpler:
keepFirstN[lst_List] := Block[{nftn},
nftn[int_, count_] := (nftn[int, count] = Nothing; int);
Block[{cnt = 1}, nftn[#, cnt++] & /@ #] & /@ lst]
Uninspiring but thought I'd play:
func[lst_] :=
Module[{res = Thread[{#, Range[Length@#]}] & /@ lst, f = Unique[]},
(f[#] = 1) & /@ Flatten[res, 1];
Cases[#, {x_, 1} :> x] & /@ Map[{#[[1]], f[#]++} &, res, {2}]]
so func[rArray]
yields:
{{4, 2, 1, 0}, {2}, {0, 0, 3, 3, 3}, {}, {3, 4}}