3
$\begingroup$

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)?

$\endgroup$
5
  • 1
    $\begingroup$ ConstantArray with Join for (1) and RandomSample for (2)? $\endgroup$
    – rm -rf
    Commented Jan 19, 2014 at 20:05
  • $\begingroup$ @rm-rf What's the difference between using ConstantArray and Array? $\endgroup$
    – KCl4
    Commented Jan 19, 2014 at 20:07
  • $\begingroup$ 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. $\endgroup$
    – rm -rf
    Commented Jan 19, 2014 at 20:11
  • $\begingroup$ @rm-rf Thanks for your comment! $\endgroup$
    – KCl4
    Commented Jan 19, 2014 at 20:17
  • $\begingroup$ ConstantArray yields a packed array. Array doesn't AFAIK. $\endgroup$ Commented Jan 19, 2014 at 20:46

3 Answers 3

3
$\begingroup$

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"}
$\endgroup$
2
$\begingroup$

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.

$\endgroup$
0
$\begingroup$

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"}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.