# What's the foo such that foo[{a, b, c}, 2] produces {a, a, b, b, c, c}?

I can define such a foo like this

foo[list_List, n_Integer] := Join @@ Transpose@ConstantArray[list, n]

foo[{3, {1, 4}, 1}, 3]

{3, 3, 3, {1, 4}, {1, 4}, {1, 4}, 1, 1, 1}


...but I could swear that there already is a built-in Mathematica function for this1. I just can't remember it.

1 ...though its signature need not be the same as foo's.

• closely related and stealing here from Simon Woods: Flatten[{#, #, #}, {{2, 1}}] &@{3, 1, 4, 1} – user1066 May 18 '17 at 18:06
• @tomd maybe foo = Table[##] ~Flatten~ {2, 1} & – Simon Woods May 18 '17 at 19:06
• @SimonWoods Very nice! – user1066 May 18 '17 at 19:15

I cannot think of a built-in function that does this more directly than what you wrote, but for the sake of variety you can also use PadRight:

fn[a_List, n_Integer] := PadRight[{a}, {n, Automatic}, a]\[Transpose] // Catenate

fn[{a, b, c}, 4]

{a, a, a, a, b, b, b, b, c, c, c, c}


If n is a power of two then you could Riffle as well:

Nest[Riffle[#, #] &, {a, b, c}, 2]

{a, a, a, a, b, b, b, b, c, c, c, c}


You could even Partition that output to get other values, though that seems rather contrived:

Join @@ Partition[%, 3, 4]

{a, a, a, b, b, b, c, c, c}


## Performance

With a small change to fn we can eliminate the Transpose operation.

f2[a_List, n_Integer] :=
Catenate @ PadRight[#, {Automatic, n}, #] & @ Partition[a, 1]


For both light and heavy replication on packed arrays this tests faster than foo and remains competitive on unpacked arrays.

(* packed *)
foo[Range@1*^6, 5]; // RepeatedTiming
fn[Range@1*^6, 5];  // RepeatedTiming
f2[Range@1*^6, 5];  // RepeatedTiming

{0.3026, Null}

{0.0547, Null}

{0.0663, Null}

(* packed, heavy replication *)
foo[Range@1000, 5000]; // RepeatedTiming
fn[Range@1000, 5000];  // RepeatedTiming
f2[Range@1000, 5000];  // RepeatedTiming

{0.053, Null}

{0.053, Null}

{0.033, Null}

(* unpackable *)
foo[1/Range@1*^6, 5]; // RepeatedTiming
fn[1/Range@1*^6, 5];  // RepeatedTiming
f2[1/Range@1*^6, 5];  // RepeatedTiming

{0.351, Null}

{0.4586, Null}

{0.4945, Null}

foo[1/Range@1000, 5000]; // RepeatedTiming
fn[1/Range@1000, 5000];  // RepeatedTiming
f2[1/Range@1000, 5000];  // RepeatedTiming

{0.0845, Null}

{0.213, Null}

{0.115, Null}

foo[list_, n_] := Catenate @ Table[e, {e, list}, n]


You can also use

f[l_List, n_Integer] := Flatten[Outer[Table, l, {n}, 1], 2]


or

ff[l_List, n_Integer] := Flatten[Thread[Table[l, n]], 1]


Both work:

f[{3, {1, 4}, 1}, 3]
ff[{3, {1, 4}, 1}, 3]


{3, 3, 3, {1, 4}, {1, 4}, {1, 4}, 1, 1, 1}

In:

f[xs_, n_] := MapThread[Sequence, ConstantArray[xs ,n]];
f[{a,b,c}, 2]

g[xs_, n_] := Sequence @@ (Table[1, n] #) & /@ xs;
g[{a,b,c}, 2]


Out:

{a, a, b, b, c, c}
{a, a, b, b, c, c}


To be readable and intuitive, I suggest:

repeatItems01[lst_List, n_Integer] := Catenate[ConstantArray[#, n] & /@ lst]

ff[v_List, n_Integer] := Last@Reap[Do[Sow[ConstantArray[i, n]], {i, v}]]~Flatten~2;

ff[{3, {1, 4}, 1}, 3]
(* {3, 3, 3, {1, 4}, {1, 4}, {1, 4}, 1, 1, 1} *)


another way:

foo[{}, _] := {};
foo[list_, num_] := Join[ConstantArray[First@list, num], foo[Rest@list, num]];
foo[{3, {1, 4}, 1}, 3]
(* {3, 3, 3, {1, 4}, {1, 4}, {1, 4}, 1, 1, 1} *)


Here's a pretty obscure way:

foo[list_, n_] := ListConvolve[ConstantArray[1, n], Upsample[list, n], 1]

foo[{a, b, c, d}, 3]
{a, a, a, b, b, b, c, c, c, d, d, d}