Error when searching through a table

Hi all,

I’m quite new to Processing and I was hoping someone could help me with this problem I have when searching through a table.

I used the control P5 library to make a search bar where the user types words separated by commas. My intention is for each word the user typed in to be searched through a table which was converted from a csv file (using loadTable()) that I added to the data folder of the sketch. If any of the words that the user typed in exists in the table, I want the category to be printed.

For example, if my spreadsheet looks like this, and the user typed in “Whale,Lizard”, I want it to print “Mammal,Reptile”:

Animal%20spreadsheet%202

This is my code for the search method:

void Search() {
  userInput = cp5.get(Textfield.class, "s").getText();
  inputArr = split(userInput, ',');
  screen =2;
  for (String s : inputArr) {
    for (String obj: ingTable.getStringColumn("Name")) {
         for (TableRow row : ingTable.matchRows(s, obj)) {
            items = items + row.getString("Name");
      }
    }
  }
  print(items);
}

Every time I run it, I get this error:

controlP5.ControlBroadcaster printMethodError
SEVERE: An error occured while forwarding a Controller event, please check your code at Search

Could someone please explain what’s wrong with my search method?
Thanks!!

1 Like

Your table seems confusing to me. :confused:
Shouldn’t it be something like this 1 below instead? :thinking:

Mammal Insect Reptile
Whale Fly Snake
Zebra Bee Lizard
Mouse Ant Crocodile

“Animals.csv”:

Mammal,Insect,Reptile
Whale,Fly,Snake
Zebra,Bee,Lizard
Mouse,Ant,Crocodile

Thank you! That makes more sense.

With that new format however, what do I put in the getStringColumn() method? I previously had getStringColumn(“Name”)

  • Those category words are the title headers of the Table.
  • We’re gonna need 1 loop for each word entry.
  • A second 1 to iterate over each TableRow of the Table.
  • And a third 1 to iterate over each column of the current TableRow.
  • Thus we need a triple loop in order to find out all categories which the word entries belong to.
  • In my solution, I’ve defined 3 functions: findTitles(), findElemTitle(), titleWord().
  • titleWord() merely capitalizes the 1st char of its String parameter.
  • findTitles() got the outer loop, which calls findElemTitle(), passing the current word, and collecting its returned String in a StringList container via the StringList::append() method.
  • findElemTitle() receives the passed word, and has a double loop for the TableRow & its columns.
  • Inside its double loop, it calls TableRow::getString() and compare it to the passed word via String::equals().
  • If they both match, findElemTitle() prematurely returns its corresponding TableRow::getColumnTitle().
  • If nothing matches after its double loop finishes, an empty String is returned instead.
/**
 * Find Title of Each Word (v1.0.2)
 * GoToLoop (2018/Aug/30)
 * Discourse.Processing.org/t/error-when-searching-through-a-table/3118/4
 */

static final String FILENAME = "Animals.csv";
static final String ANIMALS = " , whale,liZard, ant, Bee , ";
static final char DELIM = ',';

Table t;

void setup() {
  t = loadTable(FILENAME, "header");

  println(ANIMALS, ENTER);
  final String[] categories = findTitles(t, ANIMALS, DELIM);
  printArray(categories);

  exit();
}

static final String[] findTitles(final Table t, final String s, final char d) {
  if (t == null | s == null || s.isEmpty())  return new String[] {};

  final StringList sl = new StringList();

  for (final String w : trim(split(s, d))) {
    final String title = findElemTitle(t, titleWord(w));
    if (!title.isEmpty())  sl.append(title);
  }

  return sl.array();
}

static final String findElemTitle(final Table t, final String s) {
  if (t == null | s == null || s.isEmpty())  return "";

  final int cols = t.getColumnCount();

  for (final TableRow tr : t.rows())  for (int i = 0; i < cols; ++i)
    if (s.equals(tr.getString(i)))  return t.getColumnTitle(i);

  return "";
}

static final String titleWord(final String s) {
  if (s == null || s.isEmpty())  return "";

  final StringBuilder sb = new StringBuilder(s.toLowerCase());
  sb.setCharAt(0, Character.toUpperCase(s.charAt(0)));

  return sb.toString();
}
3 Likes

Yay it worked!!! Thank you so so much!! I never would’ve figured this out on my own.