# Write code smarter and better

**URL:** <https://discourse.processing.org/t/write-code-smarter-and-better/26213>\
**Category:** Coding Questions\
**Created:** [December 13, 2020, 9:23pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213 "2020-12-13T21:23:39Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![vestergaard12](https://avatars.discourse-cdn.com/v4/letter/v/c67d28/32.png) [@vestergaard12](https://discourse.processing.org/u/vestergaard12)\
**Post date:** [December 13, 2020, 9:23pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/1 "2020-12-13T21:23:39Z")

</div>

Hello Processing Foundation

How would you compromize this code, for example into a for-loop or one simple function?

```auto
   if (key == c[n]) {
      n++;
      text1[0] = text1[0].substring(0, n-1) + '-' + text1[0].substring(n, text1[0].length());
    } 

    if (key == c2[n2]) {
      n2++;
      text1[1] = text1[1].substring(0, n2-1) + '-' + text1[1].substring(n2, text1[1].length());
    } 

    if (key == c3[n3]) {
      n3++;
      text1[2] = text1[2].substring(0, n3-1) + '-' + text1[2].substring(n3, text1[2].length());
    } 
  }

```

---

<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:** [December 13, 2020, 9:49pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/2 "2020-12-13T21:49:37Z")

</div>

> [@vestergaard12](#):
>
> , for example into a for-loop…

To turn those checks into 1 loop the 1D arrays _c[]_, _c2[]_ & _c3[]_ have to become 1 single 2D array _c[][]_.

---

<div class="post-metadata">

**Author:** ![vestergaard12](https://avatars.discourse-cdn.com/v4/letter/v/c67d28/32.png) [@vestergaard12](https://discourse.processing.org/u/vestergaard12)\
**Post date:** [December 13, 2020, 9:55pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/3 "2020-12-13T21:55:46Z")

</div>

Thank you for the answer 🙂  
I will make 1 single 2d array c[][] then, but I need a little help to do this. This is the code I have for my c, c2 and c3 varible:  
(The c, c2 and c3 variables explodes a string into chars.)

```auto
char[] c, c2, c3;

void draw() {
  //...  
  c = explode(text1[0]); 
  c2 = explode(text1[1]); 
  c3 = explode(text1[2]);

char[] explode(String s_) { 
  return 
    s_.toCharArray();
}

```

---

<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:** [December 13, 2020, 10:22pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/4 "2020-12-13T22:22:32Z")

</div>

```auto
final String[] texts = { "write", "code", "smarter" };
final char[][] letters = new char[texts.length][];

void setup() {  
  for (int i = 0; i < texts.length; letters[i] = explode(texts[i++]));
  for (final char[] chars : letters) println(str(chars));
  exit();
}

static final char[] explode(final String s) { 
  return s.toCharArray();
}

```

---

<div class="post-metadata">

**Author:** ![vestergaard12](https://avatars.discourse-cdn.com/v4/letter/v/c67d28/32.png) [@vestergaard12](https://discourse.processing.org/u/vestergaard12)\
**Post date:** [December 14, 2020, 8:36pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/5 "2020-12-14T20:36:02Z")

</div>

Thank you very much, I have now done that:)  
But then how do you use that code to do this:

```auto
   if (key == c[n]) {
      n++;
      text1[0] = text1[0].substring(0, n-1) + '-' + text1[0].substring(n, text1[0].length());
    } 

    if (key == c2[n2]) {
      n2++;
      text1[1] = text1[1].substring(0, n2-1) + '-' + text1[1].substring(n2, text1[1].length());
    } 

    if (key == c3[n3]) {
      n3++;
      text1[2] = text1[2].substring(0, n3-1) + '-' + text1[2].substring(n3, text1[2].length());
    } 
  }

```

---

<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:** [December 14, 2020, 9:17pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/6 "2020-12-14T21:17:32Z")

</div>

> [@vestergaard12](#):
>
> But then how do you use that code to do this:

Your last code post above is exactly the same as your 1st code post. 😐

You haven’t created your 2D array like I had done for _letters[][]_. 😔

---

<div class="post-metadata">

**Author:** ![vestergaard12](https://avatars.discourse-cdn.com/v4/letter/v/c67d28/32.png) [@vestergaard12](https://discourse.processing.org/u/vestergaard12)\
**Post date:** [December 14, 2020, 9:49pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/7 "2020-12-14T21:49:21Z")

</div>

I am sorry for poor communication.  
I have created the 2D array “letters[][]” but the thing is that I do not know how I can change the thing my code does into your code?  
In my code (as you probably can see) I want to replace the first letter of the word with “-”, when the key pressed is equal to the front letter of the string. I want to do this by using 2d char-arrays and not the variables c, c2 and c3 which I did before 🙂

---

<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:** [December 15, 2020, 12:12am UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/8 "2020-12-15T00:12:53Z")

</div>

> [@vestergaard12](#):
>
> I want to replace the first letter of the word with “-”, when the key pressed is equal to the front letter of the string.

Something like this below: ❓

```auto
final String[] words = { "write", "code", "smarter" };

void setup() {
  noLoop();
}

void draw() {
  println(words);
}

void keyTyped() {
  println(key);

  for (int i = 0; i < words.length; ++i) {
    final String word = words[i];
    final int len = word.length() - 1;
    final int idx = min(word.lastIndexOf('-') + 1, len);
    final char ch = word.charAt(idx);

    println(len, idx, ch);

    if (ch == key) words[i] = word.replaceFirst(str(ch), "-");

    if (words[i].endsWith("-")) println("Index", i, "got no more letters!");
  }

  redraw();
}

```

[String (Java SE 11 & JDK 11 )](http://docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#lastIndexOf(int))  
[String (Java SE 11 & JDK 11 )](http://docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#replaceFirst(java.lang.String,java.lang.String))

---

<div class="post-metadata">

**Author:** ![vestergaard12](https://avatars.discourse-cdn.com/v4/letter/v/c67d28/32.png) [@vestergaard12](https://discourse.processing.org/u/vestergaard12)\
**Post date:** [December 15, 2020, 12:36am UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/9 "2020-12-15T00:36:27Z")

</div>

exactly 🙂  
If I when want the word to randomly change into another word from the string array when you have written all letters in the word, how would you set this up?

---

<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:** [December 15, 2020, 12:50am UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/10 "2020-12-15T00:50:09Z")

</div>

You can use method String::**endsWith()**: 💡  
[docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#endsWith(java.lang.String)](http://docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#endsWith(java.lang.String))  
`if (words[i].endsWith("-")) println("Index", i, "got no more letters!");`

---

<div class="post-metadata">

**Author:** ![vestergaard12](https://avatars.discourse-cdn.com/v4/letter/v/c67d28/32.png) [@vestergaard12](https://discourse.processing.org/u/vestergaard12)\
**Post date:** [December 18, 2020, 10:49am UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/11 "2020-12-18T10:49:09Z")

</div>

> [@GoToLoop](#):
>
> if (words[i].endsWith(“-”)) println(“Index”, i, “got no more letters!”);

Thank you very much, this works just as intended 🙂  
I just have one question left:  
How would you set the for-loop/code up when the string-array (words) is 2D (words) instead of 1D?  
Lets say this is the 2D string-array:

```auto
String[][] words2 = {
  {"write","code","smarter","and","better"},
  {"ok","i","will","do","so"},
  {"thank","you","very","much"},
};

```

Here I first want to select a random word from the first index of words ({“write”,“code”…) and when you have typed the random selected word correct on your computer keyboard, the word will change to another word from the first index of the string-array. When you have done this 4 times, the words should change to only be taken form the second index of the array ({“ok”,“I”,…). I hope you understand, and have a little time to help me?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 18, 2020, 12:16pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/12 "2020-12-18T12:16:05Z")

</div>

What about when you think of a solution and post your attempt here?

Then we can help you with where you stuck.

Otherwise, we would do your work. What you ask here is a project, an entire Sketch, not a question about an isolated data structure.

**Anyway**

> [@vestergaard12](#):
>
> Here I first want to select a random word from the first index of words ({“write”,“code”…) and when you have typed the random selected word correct on your computer keyboard, the word will change to another word from the first index of the string-array.

My guess would be you could make a IntList 0,1,2… and then use shuffle() on it (see reference: [shuffle() / Reference / Processing.org](https://www.processing.org/reference/IntList_shuffle_.html)) and use it as indexes.  
When you increment the index “indexForIntList” you use for IntList, you don’t have to use random() because the list is shuffled already. (Explanation: this approach is easier than to use `random()` every time and check whether this number has already been used and if so, use `random()` again…).

Then you receive the input. Word is guessed: Increase the index “indexForIntList”.

> [@vestergaard12](#):
>
> When you have done this 4 [5] times, the words should change to only be taken form the second index of the array ({“ok”,“I”,…).

Once “indexForIntList” is \>=words2[indexForWords2].length you increase indexForWords2

**Here is a quick demo for the pure data structure and IntList**

You can of course **not** use it for your Quiz since it doesn’t have the structure:

- ask user,
- receive input,
- go to next word…

A `for`-loop and `while`-loop won’t help your there, maybe states…

```auto
String[][] words2 = { // They don't have the same length!
  {"write", "code", "smarter", "and", "better"}, // 5
  {"ok", "i", "will", "do", "so"}, 
  {"thank", "you", "very", "much"}, // 4
};

int indexForWords2=0; // index #1 in String[][] words2 

// list for index # 2 in String[][] words2 
IntList listOfIndexes = new IntList(); // https://www.processing.org/reference/IntList_shuffle_.html 

void setup() {
  size(200, 200);

  while (indexForWords2 < words2.length) {

    makeListOfIndexes();

    for (int indexForIntList : listOfIndexes) {
      println( words2[indexForWords2][indexForIntList] );
    }//for

    indexForWords2++;
    println("----");

  }//while
}

void makeListOfIndexes() { // list of random numbers 
  listOfIndexes.clear(); 
  for (int i=0; i<words2[indexForWords2].length; i++) {
    listOfIndexes.append(i);
  }
  listOfIndexes.shuffle();
}
//

```

---

<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:** [December 18, 2020, 6:06pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/13 "2020-12-18T18:06:17Z")

</div>

> [@vestergaard12](#):
>
> … set the for-loop/code up when the string-array (_words[]_) is 2D (_words[][]_) instead of 1D?

> [@Chrisir](#):
>
> My guess would be you could make an IntList 0,1,2… and then use **shuffle()** on it…

So you wanna organize your words as phrases within a 2D array, right?

@Chrisir had the idea to use an IntList to **append()** & **shuffle()** indices for your 2D array.

But I think it’s more practical to use a StringList to **append()** & **shuffle()** 1 selected row of the 2D array:

> **[StringList / Reference](https://processing.org/reference/StringList.html)**
>
> Helper class for a list of String objects. Lists are designed to have some features of ArrayList, but to maintain the simplicity and efficiency of working with arrays. Functions such as …

Below is the actions of the loop from my previous sketch w/ 2D String[][] + StringList:

```auto
/**
 * Random Word Typing (v1.0.1)
 * GoToLoop (2020/Dec/18)
 * https://Discourse.Processing.org/t/write-code-smarter-and-better/26213/13
 */

static final String[][] PHRASES = {
  { "write", "code", "smarter", "and", "better" }, 
  { "ok", "i", "will", "do", "so" }, 
  { "thank", "you", "very", "much" }
};

static final String CHAR = "-";

final StringList shuffledPhrase = new StringList();

String word = CHAR;
int idx = -1;

void setup() {
  noLoop();
  pickRandomWordWithinPhrase();
}

void draw() {
  println(idx, PHRASES[idx].length - shuffledPhrase.size() - 1, word);
}

void keyTyped() {
  checkTypedKeyMatches1stLetterWithinWord();
  redraw();
}

void checkTypedKeyMatches1stLetterWithinWord() {
  final int idx = min(word.lastIndexOf(CHAR) + 1, word.length() - 1);
  final char ch = word.charAt(idx);
  if (ch == key) word = word.replaceFirst(str(ch), CHAR);
  if (word.endsWith(CHAR)) pickRandomWordWithinPhrase();
}

void pickRandomWordWithinPhrase() {
  if (shuffledPhrase.size() == 0) selectNextPhrase();
  word = shuffledPhrase.pop();
}

void selectNextPhrase() {
  idx = (idx + 1) % PHRASES.length;
  shuffledPhrase.clear();
  shuffledPhrase.append(PHRASES[idx]);
  shuffledPhrase.shuffle(this);
  println(shuffledPhrase);
}

```

---

<div class="post-metadata">

**Author:** ![vestergaard12](https://avatars.discourse-cdn.com/v4/letter/v/c67d28/32.png) [@vestergaard12](https://discourse.processing.org/u/vestergaard12)\
**Post date:** [December 18, 2020, 8:10pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/14 "2020-12-18T20:10:24Z")

</div>

Thank you very much @GoToLoop !  
I used your code and have know made it work exactly as I want 🙂  
The only thing I am having af little trouble with is that i want to put the “word”-string into a string-array (words):

```auto
String[] words = {CHAR,CHAR,CHAR};

```

I then will be able to draw 3 different “word”, and not only one at a time.

---

<div class="post-metadata">

**Author:** ![vestergaard12](https://avatars.discourse-cdn.com/v4/letter/v/c67d28/32.png) [@vestergaard12](https://discourse.processing.org/u/vestergaard12)\
**Post date:** [December 20, 2020, 6:22pm UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/15 "2020-12-20T18:22:53Z")

</div>

> [@vestergaard12](#):
>
> The only thing I am having af little trouble with is that i want to put the “word”-string into a string-array (words):

it would really help me a lot if someone could help me here…

---

<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:** [December 22, 2020, 7:33am UTC](https://discourse.processing.org/t/write-code-smarter-and-better/26213/16 "2020-12-22T07:33:53Z")

</div>

> [@vestergaard12](#):
>
> I then will be able to draw 3 different “word”, and not only one at a time.

In my sketch the statement `shuffledPhrase.append(PHRASES[idx]);` is responsible to add a selected row of PHRASES into the StringList _shuffledPhrase_.

It means that the number of strings added is determined by the _length_ of the selected row.

If you need to add exactly 3 String words you’re gonna need to call **append()** 3 times for each chosen 3 strings out of a row.

Although I’m using a StringList you may choose to switch it to a vanilla 1D array or some other container instead.

B/c we don’t know exactly your final goal our examples are just meant to give you ideas not full solutions.

That’s why you should post a complete attempt rather than telling us your most immediate problem.
