# Replicate sublist in new list

If I have a list of lists $a$ and a list of occurrences of each sublist $n$

a={ {1,1,1}, {2,2,2}, {3,3,3} }
n={1,3,2}

what is the most efficient way to get the following list?

l={{1,1,1},{2,2,2},{2,2,2},{2,2,2},{3,3,3},{3,3,3}}

My current implementation is

l=Flatten[Table[Table[a[[i]],{x,n[[i]]}],{i,Range[Length[n]]}],1]

EDIT

For the problem as posted, the fastest solution is Catenate[...] from march (inspired by J.M.) at 1.7 10^-5 seconds (AbsoluteTiming), with all other solutions being above 2 10^-5.

If I drastically increase the number of samples I want (for example multiplying n*100), then Catenate[MapThread[Table, {a, List /@ n}]]; takes 1.5 10^-3 seconds and the fastest solution by far is a[[Join @@ MapIndexed[ConstantArray[#2[[1]], #1] &, n]]]; from ubpdqn, at 7.7 10^-5.

In both cases, solutions from garej had intermediate timings.

So I guess the ideal solution depends on the exact problem (size of the array, number of samples, ...) and may or may not have a great impact on the overall performance.

• Flatten[MapThread[ConstantArray, {a, n}], 1]? Apr 4 '16 at 15:01
• @Delphine If you're using Mma 10, I think Catenate will be about 20% faster than Flatten[..., 1]. Apr 4 '16 at 15:18

a[[Join @@ MapIndexed[ConstantArray[#2[[1]], #1] &, n]]]
• Your solution is actually the fastest. Can you explain a bit what it does? Apr 5 '16 at 9:54
• @Delphine MapIndexed uses the index as position in list.ConstantArray just produces the desired number of the position. Join just makes a flat list and then you just use Part ([[...]]) to select the desired outcome. @MartinButtner notes Catenate is faster. This could also be used. Apr 5 '16 at 10:26
• @ubpdqn, If possible please tell why did not you use of Flatten instead of Join? is there any special reason? Jun 2 '16 at 19:28
• @Irreversible No special reason. Could use Join. Jun 2 '16 at 22:35
Table @@@ Transpose[{a, n}] // Catenate

{{1, 1, 1}, {2, 2, 2}, {2, 2, 2}, {2, 2, 2}, {3, 3, 3}, {3, 3, 3}}

Edit Also

Join @@ Table @@@ Thread[{a, n}]
• These are good solutions too, very elegant, but not the fastest. Apr 5 '16 at 10:10

From a comment by J.M., what I consider to be the most natural solution:

Via Martin, alternatively do

You can also do something similar using pure functions and Apply:

ConstantArray[#1, #2] & @@@ Thread[{a, n}] // Catenate;

This is just about as fast as the previous version. You can also get around having to Catenate at the end by using Sequence all along the way, i.e.

Sequence @@ ConstantArray[#1, #2] & @@@ Thread[{a, n}];

but it turns out that this is a little slower (maybe 25% slower).

I tried to come up with a ReplaceAll version, but they were all ten times slower.

The fastest so far seems to be again by J.M. Pre 10.2 version is