# 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 '14 at 20:05
@rm-rf What's the difference between using ConstantArray and Array? –  KCl4 Jan 19 '14 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 '14 at 20:11
@rm-rf Thanks for your comment! –  KCl4 Jan 19 '14 at 20:17
ConstantArray yields a packed array. Array doesn't AFAIK. –  Sjoerd C. de Vries Jan 19 '14 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.

-