# Specifying an array with a specific number of copies of two elements

To specify an array of length L in Mathematica, where each entry is someElement, I'm accustomed to writing:

exArray=Array[someElement &, L];


However, let's say that I want to (quickly) generate an array of length L where there are n copies of elementOne and L- n copies of elementTwo. Maybe elementOne is the string character A and elementTwo is the string character B. I'd like to be able to position the two elements in two different ways: (1) where the first n elements are all elementOne and the remaining elements are all elementTwo, and (2) where we have a uniform random sample from the set of all possible arrays where there are n copies of elementOne and L - n copies of elementTwo.

Are there simple "one-liners" to do (1) + (2)?

• ConstantArray with Join for (1) and RandomSample for (2)?
– rm -rf
Jan 19, 2014 at 20:05
• @rm-rf What's the difference between using ConstantArray and Array?
– KCl4
Jan 19, 2014 at 20:07
• Not much, really. Array is more flexible, but in this context, what you have and ConstantArray give the same result. You might find the 3rd argument of ConstantArray useful if you're initializing sparse arrays. I generally like to write code that "reads well", so if the intent of the line is to generate a constant array, I'll go with ConstantArray.
– rm -rf
Jan 19, 2014 at 20:11
• @rm-rf Thanks for your comment!
– KCl4
Jan 19, 2014 at 20:17
• ConstantArray yields a packed array. Array doesn't AFAIK. Jan 19, 2014 at 20:46

For requirement (1):

Join @@ ConstantArray @@@ {{"A", 5}, {"B", 3}}

{"A", "A", "A", "A", "A", "B", "B", "B"}


Then for requirement (2):

RandomSample[%]

{"A", "B", "A", "B", "A", "A", "B", "A"}


Or as a "one-liner:"

Join @@ ConstantArray @@@ {{"A", 5}, {"B", 3}} // RandomSample


Or as a function:

f[a_, b_, L_Integer, n_Integer] /; L >= n :=
Join @@ ConstantArray @@@ {{a, n}, {b, L - n}}


Now:

f["A", "B", 7, 2] // RandomSample

{"B", "A", "B", "B", "A", "B", "B"}


Extended comment about ConstantArray vs Array:

a = ConstantArray[0, 10000000]; // AbsoluteTiming
(* {0.066234, Null} *)

MaxMemoryUsed[]
MemoryInUse[]
(* 102399424 *)
(* 102175120 *)

a =.;
a = Array[0 &, 10000000]; // AbsoluteTiming
(* {0.989285, Null} *)

MaxMemoryUsed[]
MemoryInUse[]
(* 342186712 *)
(* 102188984 *)


ConstantArray is faster and more memory efficient for long numerical arrays.

MapApply and Splice came with V 13.1 and

RandomSample @ MapApply[Splice @* Table] @ {{"A", 5}, {"B", 3}}


{"A", "A", "B", "A", "B", "B", "A", "A"}