How to sort words alphabetically from a String?

Hello,
The code below compiles, but the way the words are displayed is really strange (last word on the left and then the other words on its right…) how come ?!!
I want to sort the words in alphabetical order and change their coordinates according to mouseX
A-words at the top, then B-words below and so on according to their index.
Thanks a lot already for your help.
Best,
L

String wordsList="afaint,afar,all,and,away,folly,for,from,given,glimpse,is,need,over,see,seeing,seem,that,the,there,this,to,where,what,word,";
String message;
String []lines;
boolean drawText;
PFont font;
String [] words;

//*****************************************************************************************************************************************

void setup() {
  size(1080, 1600);

  lines = loadStrings("Beckett.txt");  //link to the text
  message= join(lines, " "); // join all the words together
  lines= split(message, ","); //split the text line by line
  words = splitTokens(message, " "); // now split each line into words?!
  font = createFont("helvetica", 30);
  textFont(font);
  textAlign(LEFT);
}

//*****************************************************************************************************************************************

void draw() {
  background(0);  
  translate(500, 100);
  smooth();
  int posX = 0;
  int posY = 0;

  for (int j=0; j<words.length; j++) {
   
    int index = wordsList.indexOf(words[j]);
    //if (index<0) continue;
    float m=map(mouseX, 50, width-50, 0, 1);
    m = constrain(m, 0, 1);
    //float sortX = 0;
    //float interX = lerp(posX, sortX, m);
    float sortY =index*10+30;
    float interY = lerp(posY, sortY, m);
    posX +=textWidth(words[j])+10;
    
    if (words[j].equals(",") || words[j].indexOf(",")>0) {
      // new line 
      posX=0; 
      posY += 40;
    }

    fill(255);
    text(words[j], posX, interY);
  }
}

java.util.Arrays.sort(words);

Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/util/Arrays.html#sort(java.lang.Object[])

2 Likes

Dear @GoToLoop,
Thank you very much for your answer,
but the problem stay the same!?
I certainly don’t understand how it works…

String wordsList="folly, folly for to, for to, what is the word,";
String message;
String []lines={"folly,","folly for to,","for to,","what is the word,"};
boolean drawText;
PFont font;

//*****************************************************************************************************************************************

void setup() {
  size(1080, 1600);
  font = createFont("helvetica", 30);
  textFont(font);
  // lines = loadStrings("Beckett.txt");  //link to the text
  message= join(lines, " "); // join all the words together
  lines= split(message, ","); //split the text line by line
  java.util.Arrays.sort(lines);
}

//*****************************************************************************************************************************************

void draw() {
  background(0);  
  translate(100, 100);
  smooth();
  int posX = 0;
  int posY = 0;

  String [] words = split(message, " ");
  for (int j=0; j<words.length; j++) {
    int index = wordsList.indexOf(words[j]);
    println(index);

    if (index<0)continue;
    float m=map(mouseX, 50, width-50, 0, 1);
    m = constrain(m, 0, 1);
    float sortX = 0;
    float interX = lerp(posX, sortX, m);
    float sortY =index*10+30;
    float interY = lerp(posY, sortY, m);
    posX +=textWidth(words[j])+10;

    if (words[j].equals(",")|| words[j].indexOf(",")>0) {
      // new line 
      posX=0; 
      posY += 50;
    }

    textAlign(LEFT, LEFT);
    textSize(30);
    fill(255);
    text(words[j], posX, interY);
  }
}

Just print the array’s state before & after sort():

println("Before sorting:");
printArray(lines);

java.util.Arrays.sort(lines);

println("\nAfter sorting:");
printArray(lines);

Alternative, you can also try out Processing’s own sort() function:
Processing.org/reference/sort_.html

1 Like

Thanks for your reply @GoToLoop,
Okay I did understood, but still the order of the word is messy in x, how come?!
a problem with textWidth()?!

String wordsList="folly,folly for to,for to,what is the word";
String message;
String []lines={"folly,","folly for to,","for to,","what is the word"};
boolean drawText;
PFont font;

//*****************************************************************************************************************************************

void setup() {
  size(1080, 1600);
  font = createFont("helvetica", 30);
  textFont(font);
  // lines = loadStrings("Beckett.txt");  //link to the text
  message= join(lines, " "); // join all the words together
  lines= split(message, ","); //split the text line by line
  println("Before sorting:");
  printArray(lines);
  java.util.Arrays.sort(lines);
  println("After sorting:");
  printArray(lines);
}

//*****************************************************************************************************************************************

void draw() {
  background(0);  
  translate(100, 100);
  smooth();
  int posX = 0;
  int posY = 0;
  lines = split(message, " ");
  for (int i=0; i<lines.length; i++) {
    int index = wordsList.indexOf(lines[i]);
    if (index<0)continue;
    float m=map(mouseX, 50, width-50, 0, 1);
    m = constrain(m, 0, 1);
    float sortX = 0;
    float interX = lerp(posX, sortX, m);
    float sortY =index*10+30;
    float interY = lerp(posY, sortY, m);
    posX +=50;

    if (lines.equals(",")|| lines[i].indexOf(",")>0) {
      posX=0; 
      posY+= 50;
    }
   //textAlign(CENTER, CENTER);
    textSize(30);
    fill(255);
    text(lines[i], posX, interY);
  }
}
1 Like

There aren’t any variables named exactly word nor x in your posted code!

Also, you’re reassigning field lines w/ another String[] array inside draw():
lines = split(message, " ");

Obviously after that, the previously sort() String[] array from setup() is gone!

However, all of this is already beyond what you had specifically requested in this topic here.

I believe this is all being debated in your previous topic below:

2 Likes

I failed to help him there that’s why he started a new thread

Maybe you can help him?

2 Likes

I still don’t get what exactly the OP wants the code to do. :confused:

2 Likes

Dear @Chrisir and @GoToLoop,
Thank you very much for helping me.
I am so sorry if I cause you problems. In fact I want something very simple:

  1. I’d like to sort the words from a string (text) THIS WORKS
  2. I’d like those words to move from their original positions (posY) to a new position (interY)
    according to mouseX position THIS ALSO WORKS
  3. But before the text get transformed it is not in the wright order: the last word of each sentence is on the left and the other words on the right side. I’d like the text to look like this before changing its coordinates:
    folly
    folly for to
    for to
    what is the word
    folly from this
    all this
    folly from all this

and so on…
I hope this time I managed to explain yu clearly what I’d like to do?!
Looking forward to reading you

Hey There!

What it seems to me is when you sort the array, the comma which are present within each String foil with the order of each String. What I would do is add a comma at each position after the splitting.

for(int i = 0 ; i < lines.length - 1 ; i++){
      lines[i] = lines[i]+",";
}
1 Like

Hey @InferNova,
Thanks a lot for your answer and suggestion.
Do you mean like this ?!
Thanks in advance.
Best,
L

 String wordsList="folly, folly for to, for to, what is the word";
String message;
String []lines={"folly", "folly for to", "for to", "what is the word"};
boolean drawText;
PFont font;

//*****************************************************************************************************************************************

void setup() {
  size(1080, 1600);
  font = createFont("helvetica", 30);
  textFont(font);
  // lines = loadStrings("Beckett.txt");  //link to the text
  message= join(lines, " "); // join all the words together
  //lines= split(message, ","); //split the text line by line
  lines = split(message, " "); //split the text word by word
  println("Before sorting:");
  printArray(lines);
  java.util.Arrays.sort(lines);
  println("After sorting:");
  printArray(lines);

  for (int i=0; i<lines.length-1; i++) {
    lines[i] = lines[i]+",";
  }
}

//*****************************************************************************************************************************************

void draw() {
  background(0);  
  translate(100, 100);
  smooth();
  int posX = 0;
  int posY = 0;
  for (int i=0; i<lines.length; i++) {   
    int index = wordsList.indexOf(lines[i]);
    if (index<0)continue;
    float m=map(mouseX, 50, width-50, 0, 1);
    m = constrain(m, 0, 1);
    float sortX = 0;
    float interX = lerp(posX, sortX, m);
    float sortY =index*10+30;
    float interY = lerp(posY, sortY, m);
    posX +=textWidth(lines[i])+10;

    if (lines.equals(",")|| lines[i].indexOf(",")>0) {
      posX=0; 
      posY+= 30;
    }
    textSize(30);
    fill(255);
    text(lines[i], posX, interY);
  }
}
1 Like

Do this before you do the split and join. I meant to say after sorting not splitting.

1 Like

Thank you for your help
okay, here before splitting and after sorting…
Still same strange behavior!?

String wordsList="folly,folly for to,for to,what is the word";
String message;
String []lines={"folly,", "folly for to,", "for to,", "what is the word,"};
boolean drawText;
PFont font;

//*****************************************************************************************************************************************

void setup() {
  size(1080, 1600);
  font = createFont("helvetica", 30);
  textFont(font);

  println("Before sorting:");
  printArray(lines);
  java.util.Arrays.sort(lines);
  println("After sorting:");
  printArray(lines);

  for (int i = 0; i < lines.length-1; i++) {
    lines[i] = lines[i]+",";
  }
  // lines = loadStrings("Beckett.txt");  //link to the text
  message= join(lines, " "); // join all the words together
  lines= split(message, ","); 
  lines = split(message, " ");//split the text line by line
}

//*****************************************************************************************************************************************

void draw() {
  background(0);  
  translate(100, 100);
  smooth();
  int posX = 0;
  int posY = 0;

  for (int i=0; i<lines.length; i++) {
    int index = wordsList.indexOf(lines[i]);
    if (index<0)continue;
    float m=map(mouseX, 50, width-50, 0, 1);
    m = constrain(m, 0, 1);
    float sortX = 0;
    float interX = lerp(posX, sortX, m);
    float sortY =index*10+30;
    float interY = lerp(posY, sortY, m);
    posX +=50;

    if (lines.equals(",")|| lines[i].indexOf(",")>0) {
      posX=0; 
      posY+= 50;
    }
    //textAlign(CENTER, CENTER);
    textSize(30);
    fill(255);
    text(lines[i], posX, interY);
  }
}

You should join based on commas. And split based on commas.

1 Like

Thanks for your patience!
Now it looks better, but it doesn’t sort each word like it should so words don’t move
as they should: 1rst line: “folly”, 2nd below: “for”, then 3rd below : “is”
and so on.
How can I split now and sort the words from the String?
Thanks a lot,
L


String wordsList="folly for to what is the word";
String message;
String []lines={"folly ", "folly for to ", "for to ", "what is the word"};
boolean drawText;
PFont font;

//*****************************************************************************************************************************************

void setup() {
  size(1080, 1600);
  font = createFont("helvetica", 30);
  textFont(font);

  for (int i = 0; i < lines.length-1; i++) {
    lines[i] = lines[i]+",";
  }
  // lines = loadStrings("Beckett.txt");  //link to the text
  message = join(lines, ","); // join all the words together
  lines = split(message, ",");  //split the text line by line
  //lines = split(message, " ");
  println("Before sorting:");
  printArray(lines);
  java.util.Arrays.sort(lines);
  println("After sorting:");
  printArray(lines);
}

//*****************************************************************************************************************************************

void draw() {
  background(0);  
  translate(100, 100);
  smooth();
  int posX = 0;
  int posY = 0;

  for (int i=0; i<lines.length; i++) {
    int index = wordsList.indexOf(lines[i]);
    if (index<0)continue;

    float m=map(mouseX, 50, width-50, 0, 1);
    m = constrain(m, 0, 1);
    float sortX = 0;
    float interX = lerp(posX, sortX, m);
    float sortY =index*30+30;
    float interY = lerp(posY, sortY, m);
    posX +=textWidth(lines[i]);
    
    if ( lines.equals(" ")|| lines[i].indexOf(" ")>0) {
      posX=0; 
      posY+= 50;
    }
    textSize(30);
    fill(255);
    text(lines[i], posX, interY);
  }
}
1 Like

Sort. Then add commas then join then split.

1 Like

Dear @InferNova,

Sort?
How can I sort if I don’t join and split before?
In this case I sort the sentences only, not each word separately…

void setup() {
  size(1080, 1600);
  font = createFont("helvetica", 30);
   textFont(font);

   println("Before sorting:");
   printArray(lines);
  java.util.Arrays.sort(lines);
  println("After sorting:");
  printArray(lines);
  for (int i = 0; i < lines.length-1; i++) {
    lines[i] = lines[i]+",";
  }
  message = join(lines, ","); // join all the words together
  lines = split(message, ",");  //split the text line by line
}

Can you tell me more please?! Thanks, L

1 Like

Your array is already filled. With the items. You wanna sort then join then split.

Hey @InferNova,
Thank you for your message.
I think I am not very clear. Please find below the same code but with char() instead of String(). I’d like to achieve exactly the same thing with Strings than with char…
I hope now you see what I mean?!
Thanks a lot!

import java.util.Calendar;
PFont font;
String[]lines;
String joinedText; 
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜß,.;:!? ";
int[] counters = new int[alphabet.length()];
boolean[] drawLetters = new boolean[alphabet.length()];
float charSize;
color charColor = 0;
int posX = 20;
int posY = 50;
boolean drawLines = false;
boolean drawText = true;
String list;

//********************************************************************************************************************************************************

void setup() {
  size(1200, 1920);
  lines = loadStrings("Beckett.txt");  //laden des zu analysierenden textes
  joinedText = join(lines, " ");
  lines= split(joinedText, ",");
  font = createFont("helvetica", 25);
  textFont(font);
  for (int i = 0; i < alphabet.length(); i++) {
    drawLetters[i] = true;
  }
}

//********************************************************************************************************************************************************

void draw() {
  background(0);
  translate (50, 0);
  noStroke();
  smooth();
  posX = 10;
  posY = 100;
  float oldX = 0;
  float oldY = 0;

  String [] words = split(joinedText, " ");
  // go through all characters in the text to draw them  
  for (int i = 0; i < joinedText.length(); i++) {
    // again, find the index of the current letter in the alphabet
    String s = str(joinedText.charAt(i)).toUpperCase();
    char uppercaseChar = s.charAt(0);
    int index = alphabet.indexOf(uppercaseChar);
    if (index < 0) continue;
    fill(255, 200);
    //textSize(30);
    float sortX = index*20+40;
    float sortY = index*20+40;
    float m = map(mouseX, 50, width-50, 0, 1);
    m = constrain(m, 0, 1);
    float interY = lerp(posY, sortY, m);
    float interX = lerp(posX, sortX, m);
    if (drawLetters[index]) {
      if (drawLines) {
        if (oldX!=0 && oldY!=0) {
          noFill();
          stroke(181, 157, 0, 100);
          strokeWeight(2);
          bezier(oldX, oldY, oldX+100*noise(oldX*150), oldY-30*noise(oldY*500), oldX+20*noise(interY*500), oldY+50*noise(oldX*150), interX, interY);
        }
        oldX = posX;
        oldY = interY;
      }
      if (drawText && uppercaseChar !=',') 
        text(joinedText.charAt(i), posX, interY);
    } else {
      oldX = 0;
      oldY = 0;
    }
    posX += textWidth(joinedText.charAt(i));
    if (uppercaseChar ==',') {
      posY += 20;
      if (i>0) {
        posX = 0;
      } 
      if (i>945) {
        posY+=40;
        posX=-10;
      }
    }
  }
}

//********************************************************************************************************************************************************

void keyReleased() {

  if (key == '1') drawLines = !drawLines;
  if (key == '2') drawText = !drawText;

  if (key == '3') {
    for (int i = 0; i < alphabet.length(); i++) {
      drawLetters[i] = false;
    }
  }
  if (key == '4') {
    drawText = true;
    for (int i = 0; i < alphabet.length(); i++) {
      drawLetters[i] = true;
    }
  }
  String s = str(key).toUpperCase();
  char uppercaseKey = s.charAt(0);
  int index = alphabet.indexOf(uppercaseKey);
  if (index >= 0) {
    drawLetters[index] = !drawLetters[index];
  }
}

Dear @GoToLoop and @Chrisir,

@InferNova helped me, but now I am lost in transtaion!?
Please find here below a code with Char() replacing the Strings(). I would like to do exactly the same than in this sketch but with strings. Can you please help me?!!
Thanks a lot in advance.
Best, L

boolean drawText = true;
String list;

//********************************************************************************************************************************************************

void setup() {
  size(1200, 1920);
  lines = loadStrings("Beckett.txt");  //laden des zu analysierenden textes
  joinedText = join(lines, " ");
  lines= split(joinedText, ",");
  font = createFont("helvetica", 25);
  textFont(font);
  for (int i = 0; i < alphabet.length(); i++) {
    drawLetters[i] = true;
  }
}

//********************************************************************************************************************************************************

void draw() {
  background(0);
  translate (50, 0);
  noStroke();
  smooth();
  posX = 10;
  posY = 100;
  float oldX = 0;
  float oldY = 0;

  String [] words = split(joinedText, " ");
  // go through all characters in the text to draw them  
  for (int i = 0; i < joinedText.length(); i++) {
    // again, find the index of the current letter in the alphabet
    String s = str(joinedText.charAt(i)).toUpperCase();
    char uppercaseChar = s.charAt(0);
    int index = alphabet.indexOf(uppercaseChar);
    if (index < 0) continue;
    fill(255, 200);
    //textSize(30);
    float sortX = index*20+40;
    float sortY = index*20+40;
    float m = map(mouseX, 50, width-50, 0, 1);
    m = constrain(m, 0, 1);
    float interY = lerp(posY, sortY, m);
    float interX = lerp(posX, sortX, m);
    if (drawLetters[index]) {
      if (drawLines) {
        if (oldX!=0 && oldY!=0) {
          noFill();
          stroke(181, 157, 0, 100);
          strokeWeight(2);
          bezier(oldX, oldY, oldX+100*noise(oldX*150), oldY-30*noise(oldY*500), oldX+20*noise(interY*500), oldY+50*noise(oldX*150), interX, interY);
        }
        oldX = posX;
        oldY = interY;
      }
      if (drawText && uppercaseChar !=',') 
        text(joinedText.charAt(i), posX, interY);
    } else {
      oldX = 0;
      oldY = 0;
    }
    posX += textWidth(joinedText.charAt(i));
    if (uppercaseChar ==',') {
      posY += 20;
      if (i>0) {
        posX = 0;
      } 
      if (i>945) {
        posY+=40;
        posX=-10;
      }
    }
  }
}

//********************************************************************************************************************************************************

void keyReleased() {

  if (key == '1') drawLines = !drawLines;
  if (key == '2') drawText = !drawText;

  if (key == '3') {
    for (int i = 0; i < alphabet.length(); i++) {
      drawLetters[i] = false;
    }
  }
  if (key == '4') {
    drawText = true;
    for (int i = 0; i < alphabet.length(); i++) {
      drawLetters[i] = true;
    }
  }
  String s = str(key).toUpperCase();
  char uppercaseKey = s.charAt(0);
  int index = alphabet.indexOf(uppercaseKey);
  if (index >= 0) {
    drawLetters[index] = !drawLetters[index];
  }
}
1 Like