# How to multiply arrays (or lists)?

Noobie question here:

Is there a method that will allow me to replicate an array a variable number of times?
I am thinking of an operator similar to python’s * , which you can apply to arrays:
[ 1 , 2, 3] * 3 ==> [1,2,3 ,1,2,3 ,1,2,3,]

My use case is that I have an array of arrays representing melodic cells and I want to to construct a sequence of pitches by repeating each subarray a random number of times and combining the result. Something like the following, let’s say (I’m omitting durations for simplicity):

``````~cells = [ [ 1, 3, 5, 7], [1, 3, 2]];
~minMax = [2,5] ;
~pitches = PSeq[~cells.collect({
|item i|
var reps;
reps = rrand(minMax[0],minMax[1]);
item * reps);            // <== does not work...
}) ;
// Then PBind etc.
``````

I may be getting at this from a wrong angle, perhaps. Suggestions on better approaches gladly welcome.

Hello Cleinias,
surely there are better ways but you can do it like this:

``````(
~cells = [ [ 1, 3, 5, 7], [1, 3, 2]];
~minMax = [2,5] ;
~pitches = Pseq(
~cells.collect({
|item i|
var reps;
reps = rrand(~minMax[0], ~minMax[1]);
item ! reps;
}).flat.postln;
);
)
``````

Thanks Kesey,

I had looked carefully at the docs before posting but could not find any mention of the ! operator. Wold you mind sharing how I could have found out?

Also, please do not keep me on edge on the better ways of doing this

http://doc.sccode.org/Overviews/SymbolicNotations.html#Miscellaneous%20operators

FWIW I (almost) rigorously avoid `!` in my own code because it’s hard to find in the help – readability over concision.

In any case: Since the end goal is streaming, here are a couple of pattern-idiomatic ways:

``````~cells = [[1, 3, 5, 7], [1, 3, 2]];

(
Pswitch(
~cells.collect { |cell| Pseq(cell, 1) },
Pdup(
Pwhite(2, 5, inf),
Pn(Pseries(0, 1, ~cells.size), inf)
)
)
.asStream.nextN(50)
)

(
Pflatten(1, Pdup(Pwhite(2, 5, inf), Pseq(~cells, inf)))
.asStream.nextN(50)
)
``````

hjh

Thanks, your examples look much better indeed. Will delve into patterns further.

In SuperCollider:

[1, 2, 3] * 3 == [3, 6, 9]

and:

([1, 2, 3] ! 3).flatten == [1, 2, 3, 1, 2, 3, 1, 2, 3]

or longer:

[1, 2, 3].dup(3).flatten == [1, 2, 3, 1, 2, 3, 1, 2, 3]

You can give this a name if you like, including an operator name:

``````+ Array { !- { arg count; ^ (this ! count).flatten } }
``````

After which:

[1, 2, 3] !- 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3]

You can also give it a local name.

var df = {arg array, count; array.dup(count).flatten }; df.value([1, 2, 3], 3) == [1, 2, 3, 1, 2, 3, 1, 2, 3]

It depends how much you’re using it.

Oh, overlap, sorry. More characters to be long enough to send.

``````[1, 2, 3] ! 3

[1, 2, 3] dup: 3

[1, 2, 3].dup(3)
``````

The `!` operator is a shortcut for `.dup`

``````[1, 2, 3].dup(3).flat.sum
``````

`-> 18`

It’s only documented for class `Function`, though it’s also included as an instance method for class `Object`… so it applies to everything.

It’s often used for Multichannel Expansion… the `!` operator will always return it’s results in a single collection.