# How to sort words alphabetically from a String?

**URL:** <https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767>\
**Category:** Coding Questions\
**Created:** [July 17, 2019, 9:47pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767 "2019-07-17T21:47:38Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [April 29, 2020, 6:44pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/81 "2020-04-29T18:44:21Z")

</div>

In your last posted code you are using the matrix stack (with pushMatriix()) to find the coordinates of each letter as you draw it.

If you want to loop over your letters and find the next A, you need all those coordinates saved as absolute coordinates, and you need a sense of “next” – an ordered list; not a HashMap.

There are many ways to do this. One is:

```auto
class Letter {
  float x, y, r;
  char c;
  Letter(char c, float x, float y, float r) {
    this.x = x;
    this.y = y;
    this.r = r;
    this.c = c;
  }
}

ArrayList<Letter> letters;

```

Now make your current draw loop code a preload for your `letters` data which saves a new Letter each time. You can draw at the same time, or you can later loop over `letters` and draw each Letter at the correct place.

Then, to draw bezier curves, loop over `letters` and collect a list of the indices containing the letter you want, for example “a” – you might get back an array of indices (ints) at: [1,5,17, 19, 25 etc]. Then loop over that list starting at 1, and draw a line (or curve) from Letter x,y at idx=n to Letter x,y at idx=n-1. This will draw a line from, for example, letters.get(19) to letters.get(25).

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [April 29, 2020, 8:52pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/82 "2020-04-29T20:52:47Z")

</div>

Dear Jeremy,  
Thank you very much for your precious help!  
Actually I think did what you suggest in a sketch (here below) about the same poem but using world coordinates.  
I will try to adapt it to my actual sketch…

```auto
PFont f;
String[] lines;
String message;
String[] sentences;
String title;
String alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ2019,.;:!?\n ";
Letter[]letters;
int x, y;
float letterSize;
float[]originPositionsX = new float [alphabet.length()];
float[]originPositionsY = new float [alphabet.length()];
float stepX= 25;
char upperCaseChar;
boolean drawText = true;
boolean drawLines=false;

void setup() {
  size(1080, 1600);
  f = createFont("Arial", 5, true);
  textFont(f);
  lines = loadStrings("Beckett.txt"); //laden des zu analysierenden textes
  message = join(lines, " ");
  lines= split(message, ",");

  letters = new Letter[message.length()];
  for (int i =0; i < message.length(); i++) {  
    letters[i]= new Letter(x*100, 200+y*5, message.charAt(i), random(20, 40));   
    x +=textWidth(message.charAt(i));
  }
}

void draw() {

  background(0);
  pushMatrix();
  pushStyle();
  fill(255, 0, 0, 50);
   translate(-150, -230);
  //rotate(80);
  textSize(420);
  textLeading (150);
  text("what\nis the\nword", x+50, y);
  popStyle(); 
  popMatrix();
  translate(20, 40);
  smooth();
  x=5;
  y=0;

  for (int i =0; i < message.length(); i++) {   
    String st=str(message.charAt(i)).toUpperCase();
    upperCaseChar= st.charAt(0);
    int index = alphabet.indexOf(upperCaseChar);
    if (index < 0) continue;

    float m = map(mouseX, 50, width-50, 0, 1);
    m=constrain(m, 0, 1);
    float sortY =index*10+5;
    float sortX =stepX;
    float interY=lerp(y, sortY, m);
    float interX=lerp(x, sortX, m);
    letters[i].y=+interY;
    letters[i].x=+interX;
    x +=textWidth(message.charAt(i));
    if (st.equals(",")) {
      y+=20;
      x=-10;
    }
    if (drawLines) {
      if (originPositionsX[index] !=0 && originPositionsY[index] !=0) {
        pushMatrix();
        translate(15, 0);
        stroke(255, 200, 0, 100);
        noFill();
        strokeWeight(1); 
        //line(originPositionsX[index], originPositionsY[index],letters[i].x, letters[i].y); 
        bezier(originPositionsX[index], originPositionsY[index], letters[i].x, letters[i].y, letters[i].x, letters[i].y+interY/7, letters[i].x, letters[i].y);
        popMatrix();
      }
      originPositionsX[index]= letters[i].x;
      originPositionsY[index]= letters[i].y;
    }
    beginShape();
    //line(letters[i].x+5, letters[i].y, letters[i].x+5, letters[i].y+interY/4);
    endShape();
  }

  for (int i=0; i < letters.length; i++) { 
    println(i);

    if (i>951) {
      letters[i].x-=15;
      letters[i].y+=30;
    }

    if ( drawText) {
      if (message.charAt(i)!=',') {
        message.replace(",", "");
        letters[i].display();
      }
    }
    if (mousePressed) {
      /* letters[i].shake();*/
    } else {
      letters[i].home();
    }
  }
}

void keyReleased() {
  if (key=='1') drawLines = !drawLines;
  if (key=='2') drawText = !drawText;
}

class Letter {

  char letter;
  float homex, homey;
  float x, y;
  float sizeText;

  Letter(float _x, float _y, char letter_, float sizeText_) {
    homex=x=_x;
    homey=y=_y;
    letter=letter_;   
    sizeText= sizeText_;
  }

  void display() {
    fill(255);
    textAlign(LEFT);
    textSize(sizeText);
    text(letter, x, y);
  }

  void shake () {
    x+=random(-2, 2);
    y+= random(-2, 2);
  }

  void home() {
    x=homex;
    y=homey;
  }
}

```

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [May 12, 2020, 6:30pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/83 "2020-05-12T18:30:13Z")

</div>

Dear Jeremy,  
I hardly have time to ‘code’. Here is below where I am now. I managed to create a letter class and to draw them, but I struggle with the lines between the letters, I tried with an alphabet.indexOf(upperCaseChar), but my lines don’t link all the same letters (a with all the a’s, b with all the b’s and so on). Can you tell me what is my mistake please ?!  
Thank you very much in advance.  
Best wishes,

L

```auto
import java.util.Map;

PFont font;

String[]lines={  
  "folly folly for to for to", 
  "what is the word", 
  "folly from this all this folly from all this", 
  "given folly given all this seeing folly seeing all this this", 
  "what is the word", 
  "this this this this here all this this here folly given all this", 
  "seeing folly seeing all this this here for to", 
  "what is the word", 
  "see glimpse seem to glimpse need to seem to glimpse folly for to need to seem to glimpse what", 
  "what is the word", 
  "and where folly for to need to seem to glimpse what where where what is the word there over there away over there", 
  "afar afar away over there", 
  "afaint afaint afar away over there what what", 
  "what is the word", 
  "seeing all this all this this all this this here folly for to see what glimpse seem to glimpse need to seem to glimpse", 
  "afaint afar away over there what", 
  "folly for to need to seem to glimpse afaint afar away over there what", 
  "what", 
  "what is the word", 
  "what is the word"
};
String alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ2019,.;:!?\n ";
// --------------------------------------------------------

String[] lines2; 
String[] c1={};
String[] wordsList2;
int Size;
float r = 40;
float angle = 0;
Letter[]letters;
String message;
char lowerCaseChar;
float interY; 
float stepX = 25;
String joinedText;
int ind;
float x, y;
// Note the HashMap's "key" is a String and "value" is an Integer
HashMap<String, Integer> hmYPos = new HashMap<String, Integer>();

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

void setup() {
  size(1400, 1400);
  font = createFont("helvetica", 20);
  textFont(font);
  textAlign(CENTER);
  message = join(lines, ",");
  lines = split(message, ",");
  //println(message.length());
  letters = new Letter[message.length()];
  for (int i =0; i<message.length(); i++) {
    letters[i]= new Letter(x, y, message.charAt(i), r);
  }
  prepare();
}

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

void draw() {
  background(0);
  translate (width/2, height/2);
  smooth();
  scale(0.7);
  float posX = 0; 
  float arcLength=0;
  float posY = 0;

  float[]originPositionsX = new float [alphabet.length()];
  float[]originPositionsY = new float [alphabet.length()];

  for (int j = 0; j < lines.length; j++) {

    if ( j<=lines.length) {
      r=45*(j+1);
    }

    String[]wordsInThatLine = split(lines[j], " "); 
    for (int j2 = 0; j2 < wordsInThatLine.length; j2++) {
      int index = hmYPos.get(wordsInThatLine[j2]);

      if (index<0) continue;
      arcLength+=15;
      mouseX=constrain(mouseX, width/2, width);
      float sortY = 0;
      r= map(mouseX, width/2, width, 75+45*j+1, 150+hmYPos.get(wordsInThatLine [j2])); 
      sortY=r;
      float m=map(mouseX, width/2, width, 0, 1);
      m = constrain(m, 0, 1);
      interY = lerp(posY, sortY, m);

      for (int j3 = 0; j3 < wordsInThatLine[j2].length(); j3++) {  
        char currentChar= wordsInThatLine[j2].charAt(j3);
        letters[j3]= new Letter(posX, posY, currentChar, r);
        float w=textWidth(currentChar);
        arcLength+=w+5;
        float theta =PI+arcLength/r;

        pushMatrix();
        translate(r*cos(theta), r*sin(theta)); 
        scale(0.7);
        rotate(theta+PI/2); 
        String joinedText = join(wordsInThatLine, " ");
        String st=str(joinedText.charAt(j3)).toUpperCase();
        char upperCaseChar= st.charAt(0);
        ind = alphabet.indexOf(upperCaseChar);
        if (ind < 0) continue;
        noFill();
        stroke(181, 157, 0, 250);
        strokeWeight(1);
        line(originPositionsX[ind], originPositionsY[ind], posX, interY);

        noFill();
        strokeWeight(hmYPos.get(wordsInThatLine[j2])*0.01+0.1);
        stroke(0, 50, 220, 100);
        //ellipse(0, -10, hmYPos.get(wordsInThatLine[j2])*0.07+15, hmYPos.get(wordsInThatLine[j2])*0.07+15);
        fill(255, 200);
        textAlign(CENTER, BASELINE);
        float SText = hmYPos.get(wordsInThatLine[j2])*0.035;
        textSize(SText+20);
        letters[j3].display();
        //text(currentChar, 0, 0);
        popMatrix();

        arcLength+=w/2;
      }
    }
  }
  originPositionsX[ind]= posX;
  originPositionsY[ind]= interY;
}

//------------------------------------------------------------

void prepare() {
  HashMap<String, Integer> hm1 = new HashMap<String, Integer>();
  String message;

  message= join(lines, " "); // Join all the separated strings
  lines2=split(message, ",");// Split them into sentences according to the comas
  // Now we have a copy of the whole text

  // Init 
  wordsList2 = split(join(lines, " "), " "); // We do the same than above for a new copy to initialize the HashMap
  for (String s : wordsList2) { // We loop across the whole list of strings
    hm1.put(s.toLowerCase(), 0); // We fill the HashMap (hm1) and put the strings to lowerCase and put all at 0
    textSize(abs(hm1.get(s)*5+Size)+15); // We pass a textSize
  }

  // Counting 
  for (int i=0; i<lines2.length; i++) { // We loop across the whole strings
    String word = lines2[i].toLowerCase().trim(); // We put the strings to lowerCase and get rid of comas, points, etc.
    if (hm1.get(word) != null) { // If the HashMap is not null
      hm1.put(word, ((int) (hm1.get(word)))+1); // We fill the HashMap with the 2nd list of strings (word) and we add 1
    }
  }

  //// Using an enhanced loop to iterate over each entry
  for (Map.Entry me : hm1.entrySet()) {
    c1 = (String[]) append (c1, me.getKey());
  }//for
  c1=sort(c1); //We sort the strings according to the alphabet
  //println(c1);

  // simulate output and save the line number for each word in sorted position 
  int posY=0;
  for (String s : c1) {
    hmYPos.put( s, posY); 
    //Size=hmYPos.get(s);
    posY += 25;
  }
}
//---------------------------------------------------------------------------------

class Letter {

  char letter;
  float x, y, r;

  Letter(float _x, float _y, char _letter, float _r) {
    x=_x;
    y=_y;
    r=_r;
    letter=_letter;
  }
  void display() {
    fill(255);
    noStroke();
    text(letter, x, y);
  }
}//
//

```

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [May 13, 2020, 7:05pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/84 "2020-05-13T19:05:54Z")

</div>

Currently you are using this to place each letter.

```auto
        pushMatrix();
        translate(r*cos(theta), r*sin(theta)); 
        scale(0.7);
        rotate(theta+PI/2); 

```

You can’t rotate and translate like this if you want to know each letter’s position coordinates. You have to calculate the x, y position of each letter on the canvas and then store it. Then you will have coordinates to draw connecting lines between those coordinates.

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [May 13, 2020, 9:04pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/85 "2020-05-13T21:04:32Z")

</div>

Thank you very much for your answer @jeremydouglass!  
Not sure I get it, you mean that I first need to calculate the x,y position of each letter then I can connect lines between these coordinates and after I can use

```auto
pushMatrix();
        translate(r*cos(theta), r*sin(theta)); 
        scale(0.7);
        rotate(theta+PI/2); 

```

in order to pass polar coordinates to letters and lines?!

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [May 13, 2020, 10:39pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/86 "2020-05-13T22:39:15Z")

</div>

~~No, I mean you don’t need to push, translate, scale, at all.~~ **Edit** : ah, I think I see what you meant here. See below:

If you compute the absolute x, y, rotation of each letter, then you can use those to draw lines between them, and to draw them.

This is a simplified example of the wrong approach:

```auto
void draw() {
  background(192);
  translate(width/2, height/2);  
  for(int i=0; i <5; i++) {
    pushMatrix();
    rotate(i * TWO_PI/5);
    scale(0.7);
    translate(mouseX, 0);
    rect(-10,-10,20,20);
    popMatrix();
  }
}

```

You draw five boxes. Each time you popMatrix, the location of each box is lost. When you want to draw lines between them, you can’t – you don’t know where they are.

Now instead, consider this:

```auto
void draw() {
  background(192);
  translate(width/2, height/2);  
  ArrayList<PVector> pts = new ArrayList<PVector>();
  // compute points
  for(int i=0; i<5; i++) {
    float r = i * TWO_PI/5;
    float x = cos(r) * mouseX;
    float y = sin(r) * mouseX;
    pts.add(new PVector(x, y, r));
  }
  // draw points
  for(int i=0; i<pts.size(); i++) {
   PVector pt = pts.get(i);
   pushMatrix();
   translate(pt.x, pt.y);
   rotate(pt.z);
   scale(0.7);
   rect(-10,-10,20,20);
   popMatrix();
  }
}

```

The sketch draws the exact same results, but it works differently.

Now we know the x, y of each of our points. That makes it really easy to add lines connecting them – we know the points, so we can connect them.

```auto
void draw() {
  background(192);
  translate(width/2, height/2);  
  ArrayList<PVector> pts = new ArrayList<PVector>();
  // compute points
  for(int i=0; i<5; i++) {
    float r = i * TWO_PI/5;
    float x = cos(r) * mouseX;
    float y = sin(r) * mouseX;
    pts.add(new PVector(x, y, r));
  }
  // draw points
  for(int i=0; i<pts.size(); i++) {
   PVector pt = pts.get(i);
   pushMatrix();
   translate(pt.x, pt.y);
   rotate(pt.z);
   scale(0.7);
   rect(-10,-10,20,20);
   popMatrix();
  }
  
  // draw connecting lines
  for(int i=1; i<pts.size(); i++) {
    PVector pt0 = pts.get(i-1);
    PVector pt1 = pts.get(i);
    line(pt0.x, pt0.y, pt1.x, pt1.y);
  }
}

```

With the first approach – the one you are using, in which you translate and scale to each letter location, then throw it away – that would never work. But with the second approach, adding the lines is easy.

This can also be done with variables on a class, like letter.x, letter.y. (Currently it looks like you might have these on your Letter class but you always set them to 0). There are other ways to solve this – for example, with a function that can always return the location of a letter based on its position and other variables, rather than saving it as data. But the basic idea is the same. You need to be able to express a letter’s x,y,r explicitly, not just move the canvas matrix around.

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [May 15, 2020, 10:12am UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/87 "2020-05-15T10:12:51Z")

</div>

Thank you very very much 🙏 🙏 🙏 @jeremydouglass for taking some of your precious time explaining me in details, very clear and good pedagogical approach ! Now I hope I will manage to apply this method to my sketch with letters !!

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [May 22, 2020, 5:59pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/88 "2020-05-22T17:59:44Z")

</div>

Dear @jeremydouglass,

 ![Capture d’écran 2020-05-22 à 19.57.19](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/1809f345e5bdd56728a177679fd5e063a554ee4b.png)

Thank you very much! Thanks to you some lines connect the same letters together!  
Now what I’d like to achieve is switching between words located at different positions.  
On the 1rst circle at the center of the spiral it would give soemthing like : “folly folly for to for to” and then I’ll switch to another poem: “folly from this all this folly” moving words to other locations…  
What do you advise me to do? A switch case with the list of strings around each circle?! I hope you can help me me with this new issue. telle me if you want me to start a new topic?  
Thanks a lot Jeremy.  
Best wishes,

L

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [May 22, 2020, 6:32pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/89 "2020-05-22T18:32:04Z")

</div>

Congratulations – it looks beautiful.

> [@lolonulu](#):
>
> moving words to other locations

Do you mean that the words in the old poem will drift to their new assigned positions for words in the new poem?

Is each new poem made of only the old words rearranged, or do some words disappear and others appear?

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [May 22, 2020, 9:40pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/90 "2020-05-22T21:40:31Z")

</div>

Thank you very much @jeremydouglass for your compliment!🙏  
No new words just the same words in new assigned positions the poems inside the poem… Thank you very much for your precious help. Best,  
L

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [May 22, 2020, 11:49pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/91 "2020-05-22T23:49:46Z")

</div>

> [@lolonulu](#):
>
> the same words in new assigned positions

And do you want them to drift from one set of positions to the next over a certain period of time?

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [May 23, 2020, 12:39am UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/92 "2020-05-23T00:39:23Z")

</div>

Here is a prototype to play with. When you press a key it picks new targets at random and moves the words around the screen.

```auto
/**
 * WordListDrift
 * 2020-05-21 Jeremy Douglass - Processing 3.5.4
 * discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/90
 */
String[] words; // a list of words
PVector[] pos; // where each word is
PVector[] targets; // where each word is going

void setup() {
  size(400, 400);
  stroke(128);
  textSize(20);
  words = new String[] {"Lorem", "ipsum", "dolor", "sit", "amet"};
  pos = randomPos(words.length);
  targets = randomPos(words.length);
}

void draw() {
  background(0);
  // targets
  fill(255, 0, 0, 64);
  for (int i=0; i<targets.length; i++) {
    ellipse(targets[i].x, targets[i].y, 20, 20);
  }
  // draw lines
  for (int i=1; i<pos.length; i++) {
    line(pos[i-1].x, pos[i-1].y, pos[i].x, pos[i].y);
  }
  // draw words
  fill(255);
  for (int i=0; i<words.length; i++) {
    // move word towards next target
    pos[i].lerp(targets[i], 0.02);
    text(words[i], pos[i].x, pos[i].y);
  }
}

void keyReleased() {
  // create new random word targets
  targets = randomPos(words.length);
}

// return a list of random positions on the canvas
PVector[] randomPos(int count) {
  PVector[] pos = new PVector[count];
  for (int i=0; i<pos.length; i++) {
    pos[i] = new PVector(random(width), random(height));
  }
  return pos;
}

```

Now, say you wanted to make this a word-reorderer.

1. reorder the words and pos array – in the same way, e.g. [2, 1, 3, 0]
2. …now the words will drift to their new targets. There is no need to change the target array.

```auto
void mouseReleased() {
  reorder(1, 2, 3, 4, 0);
}

void reorder(int... idx) {
  String[] nw = new String[words.length];
  nw[0]=words[idx[0]];
  nw[1]=words[idx[1]];
  nw[2]=words[idx[2]];
  nw[3]=words[idx[3]];
  nw[4]=words[idx[4]];
  words = nw;

  PVector[] np = new PVector[pos.length];
  np[0]=pos[idx[0]];
  np[1]=pos[idx[1]];
  np[2]=pos[idx[2]];
  np[3]=pos[idx[3]];
  np[4]=pos[idx[4]];
  pos = np;
}

```

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [May 23, 2020, 8:22am UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/93 "2020-05-23T08:22:28Z")

</div>

Wahoooooo!!! Thank you so much Jeremy I didn’t expect you would have answered me in such a detailed way. I will try to play around with your code to see if I completely understand it. Thank you very much for building in the jungle of the code 🌴🙏🙏

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [June 9, 2020, 5:07pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/94 "2020-06-09T17:07:19Z")

</div>

Dear @jeremydouglass,

I have done this below, but I think there might be better ways to put that…  
Two questions: how can I know the number of words in each line in order to know which String to put into each line?!

```auto
        if (j2 <4) {
          j=0;
        }
        if (j2 >4 && j2 < 9) {
          j=1;
        }
        if (j2>9 && j2<18) {
          j=2;
        }

```

Second question: how can I use your magical lerp() ?! To go from one location to the next smoothly ?

```auto
 for (int i=0; i<words.length; i++) {
    // move word towards next target
    pos[i].lerp(targets[i], 0.02);
    text(words[i], pos[i].x, pos[i].y);

```

Here is the code below. Thank you very much in advance for your help!  
Best wishes,  
Laurent

```auto
import java.util.Map;

PFont font;

String[]lines={  
  "folly folly for to for to", 
  "what is the word", 
  "folly from this all this folly from all this"
/*"given folly given all this seeing folly seeing all this this", 
 "what is the word", 
 "this this this this here all this this here folly given all this", 
 "seeing folly seeing all this this here for to", 
 "what is the word", 
 "see glimpse seem to glimpse need to seem to glimpse folly for to need to seem to glimpse what", 
 "what is the word", 
 "and where folly for to need to seem to glimpse what where where what is the word there over there away over there", 
 "afar afar away over there", 
 "afaint afaint afar away over there what what", 
 "what is the word", 
 "seeing all this all this this all this this here folly for to see what glimpse seem to glimpse need to seem to glimpse", 
 "afaint afar away over there what", 
 "folly for to need to seem to glimpse afaint afar away over there what", 
 "what", 
 "what is the word", 
 "what is the word"*/
};
String alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ ";

String[] lines2; 
String[] c1={};
String[] wordsList2;
int Size;
float r = 45;
Letter[]letters;
//Word[]words;
String message;
String[]wordsInThatLine; 
String st;
float interY; 
PVector [] pos;
PVector [] newPos;
float[]originPositionsX = new float [alphabet.length()];
float[]originPositionsY = new float [alphabet.length()];
float posX, posY;
// Note the HashMap's "key" is a String and "value" is an Integer
HashMap<String, Integer> hmYPos = new HashMap<String, Integer>();

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

void setup() {
  size(1400, 1400);
  font = createFont("helvetica", 20);
  textFont(font);
  textAlign(CENTER, CENTER);

  message = join(lines, ",");
  lines = split(message, ",");
  wordsList2 = split(join(lines, " "), " "); 
  letters = new Letter[message.length()];
  pos = chosenPos(message.length());
  newPos = chosenPos(message.length());

  for (int i =0; i< message.length(); i++) {
    letters[i]= new Letter(pos[i].x, pos[i].y, message.charAt(i), r);
    //posX += textWidth(message.charAt(i));
  }
  prepare();
}

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

void draw() {
  background(0);
  translate (width/2, height/2);
  smooth();
  scale(0.7);

  float arcLength=0;
  for (int j = 0; j < lines.length; j++) {
    if ( j<=lines.length) {
      r=45*j+1;
    }

    for (int j2 = 0; j2 < wordsList2.length; j2++) {

      int index = hmYPos.get(wordsList2[j2]);
      if (index<0) continue;
      arcLength+=10;
      mouseX = constrain(mouseX, width/2, width);
      float sortY = 0;
      r= map(mouseX, width/2, width, 75+45*j+1, 150+hmYPos.get(wordsList2[j2])); 
      sortY=r;
      float m=map(mouseX, width/2, width, 0, 1);
      m = constrain(m, 0, 1);
      interY = lerp(posY, sortY, m);

      for (int j3 = 0; j3 < wordsList2[j2].length(); j3++) { 

        String st=str(wordsList2[j2].charAt(j3)).toUpperCase();
        char upperCaseChar = st.charAt(0);
        int ind = alphabet.indexOf(upperCaseChar);
        if (ind <0) continue;

        if (originPositionsX[ind] !=0 && originPositionsY[ind] !=0) {
          noFill();
          strokeWeight(1);
          stroke(255, 150, 0, 180);
          bezier(originPositionsX[ind], originPositionsY[ind], letters[j3].x+50, letters[j3].y+100, letters[j3].x-20, letters[j3].y-30, letters[j3].x, letters[j3].y);
        }
        originPositionsX[ind]= letters[j3].x;
        originPositionsY[ind]= letters[j3].y;
      }

      for (int j3 = 0; j3 < wordsList2[j2].length(); j3++) {  

        char currentChar= wordsList2[j2].charAt(j3);
        float w=textWidth(currentChar);       
        arcLength+=w/2+10;
        float theta = PI+arcLength/r;
        newPos[j2].x = cos(theta)*r;
        newPos[j2].y = sin(theta)*r;
        letters[j3] = new Letter(newPos[j2].x, newPos[j2].y, currentChar, r);
        pushMatrix();
        translate(letters[j3].x, letters[j3].y);
        rotate(theta+PI/2);
        noFill();
        strokeWeight(hmYPos.get(wordsList2[j2])*0.01+0.3);
        stroke(0, 0, 150, 150);
        ellipse(0, -40, hmYPos.get(wordsList2[j2])*0.07, hmYPos.get(wordsList2[j2])*0.07);
        fill(255, 200);
        textAlign(CENTER, CENTER);
        float SText = hmYPos.get(wordsList2[j2])*0.035;
        textSize(SText+20);
        //pos[j2].lerp(newPos[j2], 0.02);

        if (j2 <4) {
          j=0;
        }
        if (j2 >4 && j2 < 9) {
          j=1;
        }
        if (j2>9 && j2<18) {
          j=2;
        }
        text(currentChar, pos[j2].x, pos[j2].y);
        popMatrix();

        w=textWidth(currentChar);
        arcLength+=w/2;
      }
    }
  }
}

void mouseReleased() {

  reorder(0, 5, 11, 9, 17, 4, 15, 10, 1, 16, 8, 12, 3, 6, 13, 2, 14, 7, 18);
}
//---------------------------------------------------------------------------------------------------------------------------------------------

PVector[] chosenPos(int count) {
  PVector []pos = new PVector [count];
  for (int i =0; i<message.length(); i++) {
    pos[i]= new PVector(0, 0);
  }
  return pos;
}

//---------------------------------------------------------------------------------------------------------------------------------------------

void reorder(int...idx) {

  String []nw = new String [wordsList2.length];

  nw[0]= wordsList2[idx[0]];
  nw[1]=wordsList2[idx[1]];
  nw[2]=wordsList2[idx[2]];
  nw[3]=wordsList2[idx[3]];
  nw[4]=wordsList2[idx[4]];
  nw[5]=wordsList2[idx[5]];
  nw[6]=wordsList2[idx[6]];
  nw[7]=wordsList2[idx[7]];
  nw[8]=wordsList2[idx[8]];
  nw[9]=wordsList2[idx[9]];
  nw[10]=wordsList2[idx[10]];
  nw[11]=wordsList2[idx[11]];
  nw[12]=wordsList2[idx[12]];
  nw[13]=wordsList2[idx[13]];
  nw[14]=wordsList2[idx[14]];
  nw[15]=wordsList2[idx[15]];
  nw[16]=wordsList2[idx[16]];
  nw[17]=wordsList2[idx[17]];
  nw[18]=wordsList2[idx[18]];
  wordsList2 = nw;

  PVector[]yValues = new PVector[wordsList2.length];
  PVector[]wordsV = new PVector [wordsList2.length];

  yValues[0] = wordsV[idx[0]];
  yValues[1] = wordsV[idx[1]];  
  yValues[2] = wordsV[idx[2]]; 
  yValues[3] = wordsV[idx[3]];
  yValues[4] = wordsV[idx[4]];
  yValues[5] = wordsV[idx[5]];
  yValues[6] = wordsV[idx[6]];
  yValues[7] = wordsV[idx[7]];
  yValues[8] = wordsV[idx[8]];
  yValues[9] = wordsV[idx[9]];
  yValues[10] = wordsV[idx[10]];
  yValues[11] = wordsV[idx[11]];  
  yValues[12] = wordsV[idx[12]]; 
  yValues[13] = wordsV[idx[13]];
  yValues[14] = wordsV[idx[14]];
  yValues[15] = wordsV[idx[15]];
  yValues[16] = wordsV[idx[16]];
  yValues[17] = wordsV[idx[17]];
  yValues[18] = wordsV[idx[18]];
  yValues = wordsV;
}

//---------------------------------------------------------------------------------------------------------------------------------------------

void prepare() {
  HashMap<String, Integer> hm1 = new HashMap<String, Integer>();
  String message;

  message= join(lines, " "); // Join all the separated strings
  lines2=split(message, ",");// Split them into sentences according to the comas
  // Now we have a copy of the whole text

  // Init 
  wordsList2 = split(join(lines, " "), " "); 
  //println(wordsList2);// We do the same than above for a new copy to initialize the HashMap
  for (String s : wordsList2) { // We loop across the whole list of strings
    hm1.put(s.toLowerCase(), 0); // We fill the HashMap (hm1) and put the strings to lowerCase and put all at 0
    textSize(abs(hm1.get(s)*5+Size)+15); // We pass a textSize
  }

  // Counting 
  for (int i=0; i<lines2.length; i++) { // We loop across the whole strings
    String word = lines2[i].toLowerCase().trim(); // We put the strings to lowerCase and get rid of comas, points, etc.
    if (hm1.get(word) != null) { // If the HashMap is not null
      hm1.put(word, ((int) (hm1.get(word)))+1); // We fill the HashMap with the 2nd list of strings (word) and we add 1
    }
  }

  //// Using an enhanced loop to iterate over each entry
  for (Map.Entry me : hm1.entrySet()) {
    c1 = (String[]) append (c1, me.getKey());
  }//for
  c1=sort(c1); //We sort the strings according to the alphabet

  // simulate output and save the line number for each word in sorted position 
  int posY=0;
  for (String s : c1) {
    hmYPos.put( s, posY); 
    //Size=hmYPos.get(s);
    posY += 25;
  }
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------

class Letter {

  char letter;
  float x, y, r;

  Letter(float _x, float _y, char _letter, float _r) {
    x=_x;
    y=_y;
    r=_r;
    letter=_letter;
  }
  void display() {
    fill(255);
    noStroke();
    text(letter, x, y);
  }
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------

```

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [June 9, 2020, 9:40pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/95 "2020-06-09T21:40:06Z")

</div>

> [@lolonulu](#):
>
> how can I know the number of words in each line

With `split` and `length`.

```auto
String[] lines={  
  "folly folly for to for to", 
  "what is the word", 
  "folly from this all this folly from all this"
};

void setup() {
   println(lineLength(lines[0]));
   println(lineLength(lines[2]));
}

int lineLength (String s) {
  String[] words = split(s, ' ');
  return(words.length);
}

```

> 6  
> 9

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [June 9, 2020, 9:41pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/96 "2020-06-09T21:41:34Z")

</div>

> [@lolonulu](#):
>
> how can I use your magical lerp()

It isn’t mine – it is just a built-in method of PVector.

> **[lerp() / Reference](https://processing.org/reference/PVector_lerp_.html)**
>
> Calculates linear interpolation from one vector to another vector. (Just like regular lerp(), but for vectors.) Note that there is one static version of this method, and two…

Or, if you don’t want to use PVectors, you can also use the built-in `lerp()` on individual x and y values.

> **[lerp() / Reference](https://processing.org/reference/lerp_.html)**
>
> Calculates a number between two numbers at a specific increment. The amt parameter is the amount to interpolate between the two values where 0.0 equal to the first point, 0.1 is very near the f…

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [June 10, 2020, 1:33pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/97 "2020-06-10T13:33:24Z")

</div>

Dear @jeremydouglass,  
Thank you so so much I couldn’t find this function!  
I was looking for a way to get the index of the lines and  
the words length…I hope I’ll manage to think about it by myself next time ;))  
It’s a great lesson for me thank you very much Jeremy,  
Best,  
L

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [July 6, 2020, 4:52pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/98 "2020-07-06T16:52:35Z")

</div>

Hi @jeremydouglass,  
I am really sorry to ask you that but I don’t know how to use lerp to switch smoothly from one position to the other. It switches but changes strangely the letters positions, how come?! In addition I don’t know how to lerp on the bezier curves… I tried to solve it in a simpler sketch but couldn’t find any solution. I apologize for asking you some help once again 🙏 🙏 🙏  
Please find the code below.  
Thank you very much in advance for your help.  
Best wishes,

L

```auto

import java.util.Map;

PFont font;

String[]lines={  
  "folly folly for to for to", 
  "what is the word", 
  "folly from this all this folly from all this"
/*"given folly given all this seeing folly seeing all this this", 
 "what is the word", 
 "this this this this here all this this here folly given all this", 
 "seeing folly seeing all this this here for to", 
 "what is the word", 
 "see glimpse seem to glimpse need to seem to glimpse folly for to need to seem to glimpse what", 
 "what is the word", 
 "and where folly for to need to seem to glimpse what where where what is the word there over there away over there", 
 "afar afar away over there", 
 "afaint afaint afar away over there what what", 
 "what is the word", 
 "seeing all this all this this all this this here folly for to see what glimpse seem to glimpse need to seem to glimpse", 
 "afaint afar away over there what", 
 "folly for to need to seem to glimpse afaint afar away over there what", 
 "what", 
 "what is the word", 
 "what is the word"*/
};
String alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ ";

String[] lines2; 
String[] c1={};
String[] wordsList2;
int Size;
float r = 45;
Letter[]letters;
//Word[]words;
String message;
String[]wordsInThatLine; 
String st;
float interY; 
int ind;
PVector [] pos;
PVector [] newPos;
PVector[]originPositions;
float[]originPositionsX = new float [alphabet.length()];
float[]originPositionsY = new float [alphabet.length()];
float posX, posY;
// Note the HashMap's "key" is a String and "value" is an Integer
HashMap<String, Integer> hmYPos = new HashMap<String, Integer>();

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

void setup() {
  size(1400, 1400);
  font = createFont("helvetica", 20);
  textFont(font);
  textAlign(CENTER, CENTER);

  message = join(lines, ",");
  //println(message.length());
  lines = split(message, ",");
  wordsList2 = split(join(lines, " "), " ");
  // println(wordsList2.length);
  letters = new Letter[message.length()];
  pos = chosenPos(message.length());
  newPos = chosenPos(message.length());
  originPositions = chosenPos(message.length());
  for (int i = 0; i< message.length(); i++) {
    letters[i]= new Letter(pos[i].x, pos[i].y, message.charAt(i), r);
  }
  prepare();
}

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

void draw() {
  background(0);
  translate (width/2, height/2);
  smooth();
  scale(0.7);

  for (int j4 = 0; j4 < wordsList2.length; j4++) {
  }

  float arcLength=0;
  for (int j = 0; j < lines.length; j++) {
    if ( j<=lines.length) {
      r=45*j+1;
    }

    for (int j2 = 0; j2 < wordsList2.length; j2++) {

      int index = hmYPos.get(wordsList2[j2]);
      if (index<0) continue;
      arcLength+=10;
      mouseX = constrain(mouseX, width/2, width);
      float sortY = 0;
      r= map(mouseX, width/2, width, 75+45*j+1, 150+hmYPos.get(wordsList2[j2])); 
      sortY=r;
      float m=map(mouseX, width/2, width, 0, 1);
      m = constrain(m, 0, 1);
      interY = lerp(posY, sortY, m);

      for (int j3 = 0; j3 < wordsList2[j2].length(); j3++) { 

        String st=str(wordsList2[j2].charAt(j3)).toUpperCase();
        char upperCaseChar = st.charAt(0);
        ind = alphabet.indexOf(upperCaseChar);
        if (ind <0) continue;
        if (originPositionsX[ind] !=0 && originPositionsY[ind] !=0) {
          noFill();
          strokeWeight(1);
          stroke(255, 150, 0, 180);
          originPositions[ind].lerp(newPos[j3], 0.02);
          bezier(originPositionsX[ind], originPositionsY[ind], newPos[j3].x+50, newPos[j3].y+100, newPos[j3].x-20, newPos[j3].y-30, newPos[j3].x, newPos[j3].y);
        }
        originPositionsX[ind] = newPos[j3].x;
        originPositionsY[ind] = newPos[j3].y;
      }

      for (int j3 = 0; j3 < wordsList2[j2].length(); j3++) {  

        if (j2 < lineLength(lines[0])-2) {
          //println(lineLength(lines[0]));
          j=0;
        }
        if (j2 > lineLength(lines[0])-2 && j2 < lineLength(lines[0]+lines[1])-1) {
          j=1;
        }
        if (j2 > lineLength(lines[0]+lines[1])-1 && j2 < lineLength(lines[0]+lines[1]+lines[2])-1) {
          j=2;
        }

        char currentChar= wordsList2[j2].charAt(j3);
        float w=textWidth(currentChar);       
        arcLength+=w/2+10;
        float theta = PI+arcLength/r;
        newPos[j3].x = cos(theta)*r;
        newPos[j3].y = sin(theta)*r;
        //letters[j3] = new Letter( newPos[j3].x, newPos[j3].y, currentChar, r);
        pushMatrix();
        translate(newPos[j3].x, newPos[j3].y);
        rotate(theta+PI/2);
        noFill();
        strokeWeight(hmYPos.get(wordsList2[j2])*0.01+0.3);
        stroke(0, 0, 150, 150);
        ellipse(0, -40, hmYPos.get(wordsList2[j2])*0.07, hmYPos.get(wordsList2[j2])*0.07);
        fill(255, 200);
        textAlign(CENTER, CENTER);
        float SText = hmYPos.get(wordsList2[j2])*0.035;
        textSize(SText+20); 
        pos[j3].lerp(newPos[j3], 0.02);
        text(currentChar, pos[j3].x, pos[j3].y);
        popMatrix();
        w=textWidth(currentChar);
        arcLength+=w/2;
      }
    }
  }
}

//---------------------------------------------------------------------------------------------------------------------------------------------

void mouseReleased() {

  reorder(0, 5, 11, 9, 17, 4, 15, 10, 1, 16, 8, 12, 3, 6, 13, 2, 14, 7, 18);
}

//---------------------------------------------------------------------------------------------------------------------------------------------

PVector[] chosenPos(int count) {
  PVector []pos = new PVector [count];
  for (int i =0; i<message.length(); i++) {
    pos[i]= new PVector(0, 0);
  }
  return pos;
}

//---------------------------------------------------------------------------------------------------------------------------------------------

int lineLength (String s) {

  String [] words = split(s, ' ');
  return words.length;
}

//---------------------------------------------------------------------------------------------------------------------------------------------

void reorder(int...idx) {

  String []nw = new String [wordsList2.length];

  nw[0]= wordsList2[idx[0]];
  nw[1]=wordsList2[idx[1]];
  nw[2]=wordsList2[idx[2]];
  nw[3]=wordsList2[idx[3]];
  nw[4]=wordsList2[idx[4]];
  nw[5]=wordsList2[idx[5]];
  nw[6]=wordsList2[idx[6]];
  nw[7]=wordsList2[idx[7]];
  nw[8]=wordsList2[idx[8]];
  nw[9]=wordsList2[idx[9]];
  nw[10]=wordsList2[idx[10]];
  nw[11]=wordsList2[idx[11]];
  nw[12]=wordsList2[idx[12]];
  nw[13]=wordsList2[idx[13]];
  nw[14]=wordsList2[idx[14]];
  nw[15]=wordsList2[idx[15]];
  nw[16]=wordsList2[idx[16]];
  nw[17]=wordsList2[idx[17]];
  nw[18]=wordsList2[idx[18]];
  wordsList2 = nw;

  PVector[]yValues = new PVector[wordsList2.length];
  PVector[]wordsV = new PVector [wordsList2.length];

  yValues[0] = wordsV[idx[0]];
  yValues[1] = wordsV[idx[1]];  
  yValues[2] = wordsV[idx[2]]; 
  yValues[3] = wordsV[idx[3]];
  yValues[4] = wordsV[idx[4]];
  yValues[5] = wordsV[idx[5]];
  yValues[6] = wordsV[idx[6]];
  yValues[7] = wordsV[idx[7]];
  yValues[8] = wordsV[idx[8]];
  yValues[9] = wordsV[idx[9]];
  yValues[10] = wordsV[idx[10]];
  yValues[11] = wordsV[idx[11]];  
  yValues[12] = wordsV[idx[12]]; 
  yValues[13] = wordsV[idx[13]];
  yValues[14] = wordsV[idx[14]];
  yValues[15] = wordsV[idx[15]];
  yValues[16] = wordsV[idx[16]];
  yValues[17] = wordsV[idx[17]];
  yValues[18] = wordsV[idx[18]];
  yValues = wordsV;
}

//---------------------------------------------------------------------------------------------------------------------------------------------

void prepare() {
  HashMap<String, Integer> hm1 = new HashMap<String, Integer>();
  String message;

  message= join(lines, " "); // Join all the separated strings
  lines2=split(message, ",");// Split them into sentences according to the comas
  // Now we have a copy of the whole text

  // Init 
  wordsList2 = split(join(lines, " "), " "); 
  //println(wordsList2);// We do the same than above for a new copy to initialize the HashMap
  for (String s : wordsList2) { // We loop across the whole list of strings
    hm1.put(s.toLowerCase(), 0); // We fill the HashMap (hm1) and put the strings to lowerCase and put all at 0
    textSize(abs(hm1.get(s)*5+Size)+15); // We pass a textSize
  }

  // Counting 
  for (int i=0; i<lines2.length; i++) { // We loop across the whole strings
    String word = lines2[i].toLowerCase().trim(); // We put the strings to lowerCase and get rid of comas, points, etc.
    if (hm1.get(word) != null) { // If the HashMap is not null
      hm1.put(word, ((int) (hm1.get(word)))+1); // We fill the HashMap with the 2nd list of strings (word) and we add 1
    }
  }

  //// Using an enhanced loop to iterate over each entry
  for (Map.Entry me : hm1.entrySet()) {
    c1 = (String[]) append (c1, me.getKey());
  }//for
  c1=sort(c1); //We sort the strings according to the alphabet

  // simulate output and save the line number for each word in sorted position 
  int posY=0;
  for (String s : c1) {
    hmYPos.put( s, posY); 
    //Size=hmYPos.get(s);
    posY += 25;
  }
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------

class Letter {

  char letter;
  float x, y, r;

  Letter(float _x, float _y, char _letter, float _r) {
    x=_x;
    y=_y;
    r=_r;
    letter=_letter;
  }
  void display() {
    fill(255);
    noStroke();
    text(letter, x, y);
  }
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------

```

---

<div class="post-metadata">

**Author:** ![lolonulu](https://avatars.discourse-cdn.com/v4/letter/l/ad7895/32.png) [@lolonulu](https://discourse.processing.org/u/lolonulu)\
**Post date:** [July 10, 2020, 12:39pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/100 "2020-07-10T12:39:15Z")

</div>

Dear @jeremydouglass  
You are certainly very busy but if you can ever help me , it would be truly great. Thanks a lot. Truly tours, L

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [July 14, 2020, 9:31pm UTC](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767/101 "2020-07-14T21:31:16Z")

</div>

@lolonulu – apologies, I won’t be able to look at this in any detail until early next week.

Regarding your questions:

> I don’t know how to use lerp to switch smoothly from one position to the other.

What about it do you not understand? I provided an example sketch which demonstrates it working – can you say more about what is unclear?

> I don’t know how to lerp on the bezier curves

lerp() changes from one value to another. PVector.lerp() changes from one point to another. So if you have a curve with many points, you could change from one set of points to another set of points.

If you are using bezier(), you could just use a float for the curve arguments. Here is an example.

```auto
/**
 * LerpBezierCurves
 * 2020-07-14 Jeremy Douglass
 */
int frames = 90;
float[] c1;
float[] c2;

void setup() {
  size(400,400);
  noFill();
  c1 = randomBezier(0, width, 0, height);
  c2 = randomBezier(0, width, 0, height);
}

void draw() {
  background(255);
  
  stroke(0, 255, 0);
  bezier(c1[0], c1[1], c1[2], c1[3], c1[4], c1[5], c1[6], c1[7]);

  stroke(0, 0, 255);
  bezier(c2[0], c2[1], c2[2], c2[3], c2[4], c2[5], c2[6], c2[7]);

  float amt = (frameCount%frames)/(float)frames;
  float[] lc = lerpBezier(c1, c2, amt);
  stroke(255, 0, 0);
  bezier(lc[0], lc[1], lc[2], lc[3], lc[4], lc[5], lc[6], lc[7]);
  
  if(frameCount%(2*frames)==(2*frames-1)) reset();
}

float[] randomBezier(float xmin, float xmax, float ymin, float ymax) {
  float[] curve = new float[8];
  for(int i=0; i<4; i++) {
    curve[i*2] = random(xmin, xmax);
    curve[i*2 + 1] = random(ymin, ymax);
  }  
  return curve;
}

float[] lerpBezier(float[] b1, float[] b2, float amt) {
  float[] curve = new float[8];
  for(int i=0; i<8; i++) {
    curve[i] = lerp(b1[i], b2[i], amt);
  }  
  return curve;
}

void keyPressed() {
  reset();
}

void reset() {
  frameCount = -1;
}

```

[Previous page](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767.md?page=4)

[Next page](https://discourse.processing.org/t/how-to-sort-words-alphabetically-from-a-string/12767.md?page=6)
