How do I sort a table based on a numerical column

edited November 2015 in Library Questions

Hello everyone

So I am trying to make a highscore using a csv file where I load/save data to. I can perfectly save/load already but I want to sort the file based on the scores of the players. So I want to have the row with the higest score at top.

Using the sortReverse method on the table did not worked because it sorted the data alphabetical and not numerical. Although I add each value as a numerical value, it still sorts alphabetically.

Here is my code:

import controlP5.*;

ControlP5 cp5;
Textfield txtUsername, txtLevel;
String filePath = "highscores.csv";
Table table;
int lineCounter;

void setup() {
  size(400, 300);

  //CP5 controls
  cp5 = new ControlP5(this);
  txtUsername = cp5.addTextfield("username")
    .setPosition(20, 20)
      .setSize(100, 20)
        .setFocus(true)
          ;
  txtLevel = cp5.addTextfield("level")
    .setPosition(150, 20)
      .setSize(100, 20)
        .setFocus(false)
          ;
  cp5.addButton("submit", 0, 20, 75, 60, 20);

  readCSV();
}

void draw() {
}

void readCSV() {
  table = loadTable(filePath, "header");
  lineCounter = table.getRowCount();
  println(lineCounter + " rows in table");
  for (TableRow row : table.rows()) {
    int id=row.getInt("id");
    String username = row.getString("username");
    int level = row.getInt("level");

    println(username + " ("+level+") has an ID of "+ id);
  }
}

void saveCSV(String username, int level) {
  /*table = new Table();
  table.addColumn("id", );
  table.addColumn("username");
  table.addcolumn("level");*/

  TableRow newRow = table.addRow();
  newRow.setInt("id",table.getRowCount()-1);
  newRow.setString("username",username);
  newRow.setInt("level",level);
  table.sortReverse("level");
  saveTable(table, filePath);
}

void submit() {

  String username = txtUsername.getText();
  int level = int(txtLevel.getText());
  saveCSV(username, level);
}

So here is a screenshot of what I want:

And here is a screenshot of what I get:

Answers

  • when level is alphabetical value store it with a leading zero

    when displaying it, leave the zero

  • edited May 2014

    Same problem

    image alt text

  • edited May 2014

    Ugh what a stupid mistake

    void saveCSV(String username, int level) {
      TableRow newRow = table.addRow();
      newRow.setInt("id", table.getRowCount()-1);
      newRow.setString("username", username);
      newRow.setInt("level", level);
    
      table.sortReverse(int("level"));
    
      saveTable(table, filePath);
    }
    

    I had to specifically put int() at the sortReverse method. althoughI read level as an int and add is as an int. I still have to specifically mention in the sortReverse method that level is an int datatype.

    I found the answer here:

    image alt text

  • I see

    ;-)

  • edited May 2014

    I'm glad it's working now, but here's a little addendum... :-B

    Class Table allows us to select a column either by its String name or by its index value.
    So table.sortReverse("level"); would sort the "level" column contents. B/c you're passing a String!

    However, the other overloaded form your "fix" use is the following: table.sortReverse(int("level"));
    It's gonna sort the column whose index is 0. Not necessarily column "level"!
    B/c String "level", which is an invalid # representation, is converted to 0 by int()! 8-}

    It means that something like table.sortReverse(0); would get ya the very same "fix" solution! Got it? >:)

  • edited May 2014 Answer ✓

    Maybe the problem is more related that column contents by default are of String type? :-/
    In order to bind a column to a specific type, use method setColumnType() after creating or loadTable().

    Take a peek at my tweaked example in the thread below:
    http://forum.processing.org/two/discussion/4721/table-add-colum

  • Thanks gotoloop, well spotted indeed!

    Btw : or use 2 leading zeros?

  • edited May 2014

    Yea as a matter of fact: It's still not working actually. I'm gonna try setColumnType() and see if it works then.

    Edit: setting the column to int did it! Thanks a lot guys for your help!

    I'll post the final code for anyone interested:

    import controlP5.*;
    
    ControlP5 cp5;
    Textfield txtUsername, txtLevel;
    String filePath = "hiscores.csv";
    Table table;
    int lineCounter;
    
    void setup() {
      size(400, 300);
    
      //CP5 controls
      cp5 = new ControlP5(this);
      txtUsername = cp5.addTextfield("username")
        .setPosition(20, 20)
          .setSize(100, 20)
            .setFocus(true)
              ;
      txtLevel = cp5.addTextfield("level")
        .setPosition(150, 20)
          .setSize(100, 20)
            .setFocus(false)
              ;
      cp5.addButton("submit", 0, 20, 75, 60, 20);
    
      readCSV();
    }
    
    void draw() {
    }
    
    void readCSV() {
      table = loadTable(filePath, "header");
      lineCounter = table.getRowCount();
    
      table.setColumnType("level", Table.INT); //THIS FIXED IT
      for (TableRow row : table.rows()) {
        //Action for each row
      }
    }
    
    void saveCSV(String username, int level) { 
      TableRow newRow = table.addRow();
      newRow.setInt("id", table.getRowCount()-1);
      newRow.setString("username", username);
      newRow.setInt("level", level);
    
      table.sortReverse(2);
      saveTable(table, filePath);
    }
    
    void submit() {
      String username = txtUsername.getText();
      int level = int(txtLevel.getText());
      saveCSV(username, level);
    }
    

    Screenie:

    image alt text

  • edited May 2014

    Just 2 extra tidbits:

    1. We can replace getRowCount()-1 expression w/ lastRowIndex() method.
    2. I believe it's neater to use sortReverse("level"); rather than sortReverse(2);.
      Although the latter is a lil' faster!

    Congratz for the fix! <:-P

Sign In or Register to comment.