### expand vex array from [A,B,C] to [A,A,A,B,B,C,C] ?

2112   4   3
Member
814 posts
Joined: Feb. 2016
Offline
I have an array and I need to expand it by a given amount, by reusing its values for the new indices, so that each new value is inserted next to its source value.
Like in the title, say I want to expand it by 4, then I should get 2 new A, 1 new B, 1 new C, and the expanded array will be:
```[A,A,A, B,B, C,C]
```

My code kind of works 'till the delta newArray-oldArray is <= of the size of the old array. After that threshold, the insert() function would append out-of-bounds-Zeroes for the rest of the loop.

```i[]@array = {1,2,3,4,5};
int count;

for(int i=0; i<10; i++)
{
count = i % len(i[]@array);
insert(i[]@array,  count+=i , i[]@array[count]);

}
// return: [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
```

Any idea how to make it work?
Thanks a lot!
Edited by Andr - Feb. 13, 2019 11:07:07

Attachments:
Q_array_expand.hiplc (116.6 KB)

Member
402 posts
Joined: June 2014
Offline
Hi Andr,

This was fun There are simpler approaches using a temporary array, but makes a nice challenge trying to do it without (it's possible that it would end up faster too, but how big an array we'd need in order to notice… I'm not sure).

Have a gander and see what you think:
```// need to expand the array size by a variable amount, so that its original elements are repeated evenly
// original array [A,B,C], expanded by 4 should return: [A,A,A,B,B,C,C]

i[]@array = {1,2,3,4,5};

int expand_count = chi("expand");
int input_len = len(i[]@array);
int output_len = input_len + expand_count;
// vex may well optimize this for us, but still a good habit to
// resize an array only once if we know the desired array size in advance
// rather than call append() or insert() inside a loop
resize(i[]@array, output_len);

for(int i=input_len; i>0; i--)
{
// we want to write out the i-th input value to the highest 'unwritten'
// output index until i doesn't fit in our unwritten range
int inner_loop = output_len/i;
for(int j=0; j<inner_loop; j++)
{
// write the i-th input value to the end of the unwritten portion
// of the output array
i[]@array[output_len-1] = i[]@array[i-1];
// reduce the size of the unwritten portion
output_len--;
}
}
```

I haven't had a change to properly untangle what was up with your original code, but my first guess is that you were getting bitten by the data dependencies between ‘count’ and 'i@array' inside the loop.

Cheers!
Henry Dean
Member
814 posts
Joined: Feb. 2016
Offline
Hello Henry, thanks a lot for reviewing my code and for the nice tips.
Your approach is clever, and very exotic to me: I've never used nested loops in that fashion, where the two loops are mutually dependent.
After spending some time on it I think I start to understand the logic.

thanks again
Member
245 posts
Joined: Sept. 2008
Offline
hi. this was cool to try out but i now need to modify this so that i can use it for an interactive typewriter effect. (i have seen some typewriter effect demos/files but they are not interactive).

what i need is to grow an array at every keystroke entry from a keyboard CHOP. i have the logic to map the channels from the keyboard chop (letters A, B, C, etc, numbers 0, 1, 2, etc) to an array value, working. however i get stuck on the part to grow the array and have each new array replace the old one. in other words the array values would look like this in order at each keyboard stroke:

initialize the array s@myarr;
>>>> type "A", array result would be {A}
>>>> type a subsequent "C", array result would be {A, C}
>>>> type a third letter "F", array result would be {A, C, F}
>>>> then type a backspace (NUM-0), array result would be {A, C}
>>>> type a new letter "G", array result would be {A, C, G}

if I can get that to work then I can convert the entire array into a single compounded string "ACG" which would be displayed with the Font SOP using a points() expression, for example.