# Repeating and randomizing string arrays

**URL:** <https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811>\
**Category:** Libraries\
**Created:** [May 1, 2019, 3:12pm UTC](https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811 "2019-05-01T15:12:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![AwreetusAwrightus](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/awreetusawrightus/32/4697_2.png) [@AwreetusAwrightus](https://discourse.processing.org/u/AwreetusAwrightus)\
**Post date:** [May 1, 2019, 3:12pm UTC](https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811/1 "2019-05-01T15:12:52Z")

</div>

hello everyone!

it’s quite a simple question, but I tried to repeat values I have on an existing string array and then randomizing their positions.

using a ‘for’ method I returned out of bounds, presumably because I didn’t declared the string length properly. for that, I used expand(), which didn’t allow me for some odd reasons. (I researched a little bit and it seems the expand function doesn’t work very well for 2D arrays)

then I tried the copyArray() function, but it also returned of out bounds, since my length isn’t yet correct.

all that said and no code posted, I just wanted to gather some examples of string arrays having its values repeated and then shuffled.

thanks all for the attention!

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 1, 2019, 3:47pm UTC](https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811/2 "2019-05-01T15:47:56Z")

</div>

> [@Questions about my Color Array](https://discourse.processing.org/t/questions-about-my-color-array/3110/5):
>
> I didn’t bother warning about that b/c the colors[] array already had 3 elements in it. relieved BtW, here’s an even shorter version w/ just while () instead of do // while (): smirk_cat void pick() { int newIndex; while ((newIndex = (int) random(colors.length)) == index); index = newIndex; } Nonetheless, a custom shuffle() approach (from my previous posted link) is much more commendable: grin @ SafeVarargs final int[] shuffle(final int... arr) { if (arr == null) return null;…

> [@Color Shuffle with hex color codes](https://discourse.processing.org/t/color-shuffle-with-hex-color-codes/1191/11):
>
> The better & more performant way is to rely on IntList instead, as I had already linked to at my 1st reply: wink[https://Processing.org/reference/IntList.html](https://Processing.org/reference/IntList.html) You’ll have access to better methods, such as shuffle() & array(): muscle[https://Processing.org/reference/IntList\_shuffle\_.html](https://Processing.org/reference/IntList_shuffle_.html)[https://Processing.org/reference/IntList\_array\_.html](https://Processing.org/reference/IntList_array_.html)

---

<div class="post-metadata">

**Author:** ![AwreetusAwrightus](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/awreetusawrightus/32/4697_2.png) [@AwreetusAwrightus](https://discourse.processing.org/u/AwreetusAwrightus)\
**Post date:** [May 4, 2019, 2:42pm UTC](https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811/3 "2019-05-04T14:42:41Z")

</div>

hey Loop! once again you are there for the rescue, thanks a lot!

the thing is, and I might be aware that it should be a lack of knowledge issue on my part, I don’t know the specifics on using arrays, strings, lists and all of those.

```auto
/*

 enTro
 
 
 */

import controlP5.*;
import processing.video.*;

ControlP5 cp5;
Capture cam;

Textfield infosInput; // naming textfield for better calling throughout the code

int state = 0;
int MAXSTATE = 6; // numbers of questions to implement switch/case

String infos;
String infosOutput[];
String infosOutputFilled[];

void setup() {

  size (500, 500);

 // String[] cameras = Capture.list();

  cp5 = new ControlP5(this);

  cp5.addTextarea("titulo")
    .setPosition(100, 100)
    .setSize(400, 40)
    .setFont(createFont("arial", 30))
    .setLineHeight(14)
    .setColor(color(128))
    .setColorBackground(color(185, 100))
    .setColorForeground(color(255, 100))
    .setText("enTro");

  cp5.addTextarea("clique")
    .setPosition(280, 295)
    .setSize(200, 25)
    .setFont(createFont("arial", 12))
    .setLineHeight(14)
    .setColor(color(135))
    .setColorBackground(color(198, 100))
    .setColorForeground(color(255, 100))
    .setText("ENTER para continuar...")
    ;

  infosInput = cp5.addTextfield("") //declared earlier, I name the textfield to aid later calling
    .setPosition(120, 100)
    .setSize(390, 30)
    .setFont(createFont("arial", 30))
    .setColor(color(128))
    .setColorBackground(color(185, 100))
    .setColorForeground(color(255, 100))
    ;

  cp5.addTextarea("nome")
    .setPosition(20, 350)
    .setSize(320, 40)
    .setFont(createFont("arial", 26))
    .setLineHeight(14)
    .setColor(color(120))
    .setColorBackground(color(195, 100))
    .setColorForeground(color(249, 100))
    .setText("digite seu nome");

  /* camera settings 

  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) {
      println(cameras[i]);
    }

    // The camera can be initialized directly using an 
    // element from the array returned by list():
    cam = new Capture(this, cameras[0]);
  } */
}

void draw() {

  background(0);

  // if (cam.available() == true) {
  // cam.read();
  // } 

  switch (state) {
  case 0: //splash screen
    cp5.get(Textarea.class, "titulo").setVisible(true);
    cp5.get(Textarea.class, "clique").setVisible(false);
    cp5.get(Textarea.class, "nome").setVisible(false);
    cp5.get(Textfield.class, "").setVisible(false);
    break;

  case 1: //enter to continue
    cp5.get(Textarea.class, "titulo").setVisible(true);
    cp5.get(Textarea.class, "clique").setVisible(true);
    break;

  case 2: //user inputs their name
    // cam.start();
    cp5.get(Textarea.class, "titulo").setVisible(false);
    cp5.get(Textarea.class, "clique").setVisible(false); //hides unused textfields
    cp5.get(Textfield.class, "").setVisible(true);
    cp5.get(Textfield.class, "").setPosition(120, 100);
    cp5.get(Textarea.class, "nome").setVisible(true);
    cp5.get(Textarea.class, "nome").setText("digite seu nome");
    cp5.get(Textarea.class, "nome").setPosition(20, 350);
    // saveFrame();
    break;

  case 3: //user inputs their age
    cp5.get(Textfield.class, "").setPosition(180, 80);
    cp5.get(Textarea.class, "nome").setText("digite sua idade"); //changes the question of the box, in order to avoid creating multiple fields
    cp5.get(Textarea.class, "nome").setPosition(30, 280); //slightly changes the position for aesthetics
    // saveFrame();
    break;  

  case 4: //user inputs their nationality
    cp5.get(Textfield.class, "").setPosition(100, 90);
    cp5.get(Textarea.class, "nome").setText("digite sua nacionalidade"); 
    cp5.get(Textarea.class, "nome").setPosition(45, 200);
    // saveFrame();
    break;

  case 5: //user inputs their belief
    cp5.get(Textfield.class, "").setPosition(180, 140);
    cp5.get(Textarea.class, "nome").setText("descreva sua religião"); 
    cp5.get(Textarea.class, "nome").setPosition(250, 120);
    // saveFrame();
    break;

  case 6: //user inputs their skin tone
    // cam.stop();
    cp5.get(Textfield.class, "").setPosition(230, 80);
    cp5.get(Textarea.class, "nome").setText("qual sua descrição fenotípica");
    cp5.get(Textarea.class, "nome").setSize(420, 40); 
    cp5.get(Textarea.class, "nome").setPosition(95, 30);
    break;
  }
}

void keyPressed() {
  
  for (int j=0; j<=100; j++) {
  infosOutput = infosOutput + infosOutput[j];
  infosOutputFilled = infosOutputFilled + infosOutputFilled[j];
  }

  if ( key == ENTER || key == RETURN)
  {
    /*
     
     this step is reserved for saving the string into a .txt, but it raises the question: is it better to do
     after each single keypress or at the very end of the program, when a whole string is formed?
     
     that written, need to research a method for:
     
     - saving textfield into a .txt;
     - each answer from the user is stored in the same .txt;
     - preferrably in this step I already multiply randomly the answers throughout the strings, in order to generate a treemap afterwards:
     http://www.generative-gestaltung.de/2/sketches/?01_P/P_3_1_4_01;
     
     */
    if (state > 1)
    {
      // even in state 3 we execute the following lines and save afterwards (so please no else if)
      infos = infos + "#" + infosInput.getText();
      infosInput.setText("");
      println("boink: "+infos);
    }  
    if (state == 6)
    {
      
      // saving 
      infos=infos.trim(); 
      if (infos.charAt(0) == '#') 
        infos=infos.substring(1); // delete leading # 
      // println("new:"+infos); 
      String[] infosOutput1 = split(infos, '#');
      
      //expanding string with the information
      infosOutput1 = expand(infosOutput1, 100);

      //randomizing its contents
      for (int j=0; j<100; j++)
      {
        arrayCopy(infosOutput1, j, infosOutput1, j+4, 100);
      }

      // reference says: saveStrings(filename, data)
      saveStrings(infosOutput1[0] + ".txt", infosOutput1);
      // println(infos);
    } 
    if (state==0) {
      // reset
      infos="";
    }

    state = (state+1) % (MAXSTATE+1);

    println(state);
  }
}

```

I think you remember this; in line 189 I try to expand and then randomize. in this particular case I’m showing, having the array filled with the already present information and then randomized, would you recommend using the hex color code, using String arrays? once again I’m not familiar with some classes, I come from a very basic C background and jumped right to Processing.

if that is the case, I’ll try to replace everything in my code with that, and if you have any readings aside from the reference I’d be thankful to have a look at!

thanks again!

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 7, 2019, 6:44pm UTC](https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811/4 "2019-05-07T18:44:30Z")

</div>

> [@AwreetusAwrightus](#):
>
> I think you remember this; in line 189 I try to expand and then randomize.

Is this the line 189: `String[] infosOutput1 = split(infos, '#');`  
Sorry, can you be more specific?

---

<div class="post-metadata">

**Author:** ![AwreetusAwrightus](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/awreetusawrightus/32/4697_2.png) [@AwreetusAwrightus](https://discourse.processing.org/u/AwreetusAwrightus)\
**Post date:** [May 9, 2019, 3:28am UTC](https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811/5 "2019-05-09T03:28:05Z")

</div>

actually, those lines starting from here

```auto
//expanding string with the information
      infosOutput1 = expand(infosOutput1, 100);

      //randomizing its contents
      for (int j=0; j<100; j++)
      {
        arrayCopy(infosOutput1, j, infosOutput1, j+4, 100);
      }

```

I tried to use expand and then arrayCopy, and neither worked… I’m not sure this a case-specific compared to those you shown me, but since I’m storing letters and such it didn’t behave as I expected!

thanks a lot

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 9, 2019, 3:57am UTC](https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811/6 "2019-05-09T03:57:21Z")

</div>

> [@AwreetusAwrightus](#):
>
> I’m not sure this a case-specific compared to those you shown me,

The **shuffle()** function from the 1st link I’ve posted is for arrays of datatype `int` only:

```auto
@SafeVarargs final int[] shuffle(final int... arr) {
  if (arr == null) return null;
 
  int idx = arr.length;
 
  while (idx > 1) { 
    final int rnd = (int) random(idx--), tmp = arr[idx];
    arr[idx] = arr[rnd];
    arr[rnd] = tmp;
  }
 
  return arr;
}

```

For object-typed arrays, we need to convert it, like this:

```auto
@SafeVarargs final <T> T[] shuffle(final T... arr) {
  if (arr == null) return null;

  int idx = arr.length;

  while (idx > 1) { 
    final int rnd = (int) random(idx--);
    final T tmp = arr[idx];

    arr[idx] = arr[rnd];
    arr[rnd] = tmp;
  }

  return arr;
}

```

Alternatively, as the 2nd posted link advises, we can use the not-so-new Processing containers.

For strings, we use a StringList: [StringList / Reference / Processing.org](https://Processing.org/reference/StringList.html)

So we can have access to its methods StringList::**shuffle()** & StringList::**array()**:

1. [shuffle() / Reference / Processing.org](http://Processing.org/reference/StringList_shuffle_.html)
2. [array() / Reference / Processing.org](http://Processing.org/reference/StringList_array_.html)

---

<div class="post-metadata">

**Author:** ![AwreetusAwrightus](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/awreetusawrightus/32/4697_2.png) [@AwreetusAwrightus](https://discourse.processing.org/u/AwreetusAwrightus)\
**Post date:** [May 9, 2019, 10:26pm UTC](https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811/7 "2019-05-09T22:26:57Z")

</div>

ohyeah!

things have been worked out!

I got some issues before shuffling since my String needed to be filled first, so I kinda brute forced it

```auto
// println("new:"+infos); 
      String[] infosOutput1 = split(infos, '#');
      String[] infosOutput2 = split(infos, '#'); //saving index

      //expanding string with the information
      infosOutput1 = expand(infosOutput1, 1000);

      for (int j = 4; j < 999; j++)
      { 
        infosOutput1[j+1] = infosOutput1[k];
        k++;

        if (k > 4) //paying attention on k value related to state/questions value!!!!!
        {
          k = 0;
        }
      }

```

and then used your shuffle solution!

just to clarify and not copyn’n’paste it, the syntax

```auto
final String[] shuffle(final String... arr) 

```

means that it’s a ‘final’ variable, String Class, using String argument later named ‘arr’, right? but what’s up with those ellipsis ‘…’? and what is the purpose of the last line inside shuffle()?

```auto
arr[rnd] = tmp;

```

but then again you helped me a lot! I will have some more questions later on, but I’ll create some new topics for it. cya

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 10, 2019, 3:29am UTC](https://discourse.processing.org/t/repeating-and-randomizing-string-arrays/10811/8 "2019-05-10T03:29:52Z")

</div>

> [@AwreetusAwrightus](#):
>
> But what’s up with those ellipsis ‘…’?

> **[Java Varargs | Java Variable Arguments - javatpoint](https://www.javatpoint.com/varargs)**
>
> Java Varargs | Java Variable Arguments - The varrags allows the method to accept zero or muliple arguments. Before varargs either we use overloaded method or take an array as the method parameter but it was not considered good because it leads to the...

> [@AwreetusAwrightus](#):
>
> `arr[idx] = arr[rnd];`  
> `arr[rnd] = tmp;`

Upper expression assigns a randomly chosen index `[rnd]` to the current index `[idx]`.

After that, the randomly chosen index `[rnd]` is assigned w/ the previous index `[idx]` value _tmp_.

That is effectively a value swapping between the randomly chosen index `[rnd]` & the current index `[idx]`.

For more info about this Fisher–Yates shuffling algorithm, go here: [Fisher–Yates Shuffle](http://Bost.Ocks.org/mike/shuffle/)
