Repeat an Array element n times at index

Hello, it’s extremely simple but it’s not present in the Array documentation. As the [ ].stutter() or [ ].dupeach() method don’t allow to choose an index what is the simpliest way of doing it ? Like:

a = [ 1, 2, 3, 4, 5, 6]
/// duplicate index 2, 4 times
a = [1, 2, 3, 3, 3, 3, 4 , 5, 6];

Thanks

How about slices, duplication and concat?

a[1...(i-1)] ++ a[i]!n ++ a[(i+1)...(a.size-1)]

On phone, haven’t tested this, can’t remember if it’s double dot or triple.

Thanks Jordan, I adapted your idea like that :

(

b = [1, 2, 3, 4, 5, 6];

i = 2; // index
n = 3; // number of repetitions
c = b[i]!(n-1);

d = b.lace(i) ++ c ++ b.copyRange(i, b.size);

)

But I m wondering if there is a shorter and more elegant way !

A slightly more expressive version with flatten, depending on your goals:

// one line
(
a = [1, 2, 3 ! 3, 4, 5, 6].flatten; // > [ 1, 2, 3, 3, 3, 4, 5, 6 ]
)

// two lines
(
a = [1, 2, 3, 4, 5, 6];
a = a.instill(2, a[2] ! 3).flatten; // > [ 1, 2, 3, 3, 3, 4, 5, 6 ]
)

// three lines
(
a = [1, 2, 3, 4, 5, 6];
a[2] = a[2] ! 3;
a = a.flatten; // > [ 1, 2, 3, 3, 3, 4, 5, 6 ]
)

// generic version
(
a = [1, 2, 3, 4, 5, 6];
b = (2: 3); // which indices get how many duplications
a = a.collect({ |v, i| v ! (b[i] ? 1) }).flatten;
)
4 Likes

That’s great, thank you

Also, in this case, I want to pick up randomly 3 different blocks in the middle of the array and then put them back inside with duplication, which can create cool trance patterns, example

original : [1, 2, 3, 4, 5, 6];
result : [ 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 2, 2, 3, 4, 5, 6, 1, 2, 3. etc...

It works well but this syntax is quite heavy, what is possible to make it more ergonomic and elegant ? Thanks

The code:

(

a = [1, 2, 3, 4, 5, 6];

~minrepeat = 1;
~maxrepeat = 3;

~start_idx = rrand(0, a.size);
~end_idx =   rrand(0, a.size);

~dup = rrand(~minrepeat, ~maxrepeat);

~start_idx2 = rrand(0, a.size);
~end_idx2 =   rrand(0, a.size);
~dup2 = rrand(~minrepeat, ~maxrepeat);

~start_idx3 = rrand(0, a.size);
~end_idx3 = rrand(0, a.size);
~dup3 = rrand(~minrepeat, ~maxrepeat);

b = a.insert(~start_idx, a.copyRange(~start_idx, ~end_idx)!~dup).flat;

c = a.insert(~start_idx2, a.copyRange(~start_idx2, ~end_idx2)!~dup2).flat;

d = a.insert(~start_idx3, a.copyRange(~start_idx3, ~end_idx3)!~dup3).flat;

e = (b ++ c ++ d).postln;

)

something like this:

(
~insertDuplication = { |input, minRepeat, maxRepeat|
	var size = input.size;
	3.collect{
		var start = rrand(0, size);
		var end = rrand(0, size);
		var dup = rrand(minRepeat, maxRepeat);
		input.insert(start, input.copyRange(start, end) ! dup).flat;
	}.flat;	
};
)

(
var array = [1, 2, 3, 4, 5, 6];
~insertDuplication.(array, 1, 3);
)

That’s super, thank you !