jackoverflow jackoverflow - 1 month ago 5
Java Question

P5: Remove TableRows containing Null/NaN

The aim is to return a clean table that only includes rows that have numeric data within them, from a nominated column.
The code below works for me. But I can’t help but feel there is a better way to do this. Any thoughts on a more elegant solution?

I have the code:

Table removeEmptyRows(Table data, String column_name)
{
IntList rows_to_remove = new IntList();
Table dataCopy = cloneTable(data);

for (int r = 0; r<dataCopy.getRowCount(); r++)
{
String value_string = dataCopy.getString(r, column_name);
///filter out the NaNs
if ( ! isNullOrBlank(value_string))
{
if ( ! isNumeric(value_string) )
{
rows_to_remove.append(r);
}
} else {
rows_to_remove.append(r);
}
}


rows_to_remove.sortReverse();

for (int r : rows_to_remove)
{
dataCopy.removeRow(r);
}

return dataCopy;
}

boolean isNumeric(String inputData) {
return inputData.matches("[-+]?\\d+(\\.\\d+)?");
}

private static boolean isNullOrBlank(String s)
{
return (s==null || s.trim().equals(""));
}

Answer

This question might be a better fit at the Code Review Stack Exchange (note that if you post there, please link between crossposts and make sure you post a true MCVE and make it clear that this is a Processing, not Java question), but I'll try to offer some input.

You can simplify your code by adding good rows instead of removing bad rows. Create the returnTable by copying just the columns from the inputTable, then loop over inputTable and only add the valid rows.

Also, take a look at this if statement:

if ( ! isNullOrBlank(value_string) ) {
    if ( ! isNumeric(value_string) ) {
        rows_to_remove.append(r);
    }
} 
else {
    rows_to_remove.append(r);
}

This will keep a row in one case: if the value is not null or blank and if it is numeric. You can rewrite this logic using a single if statement:

if (!isNullOrBlank(rowValue) && isNumeric(rowValue)){

Putting it all together, it looks like this:

Table removeEmptyRows(Table inputTable, String columnName){

  Table returnTable = cloneTable(inputTable);
  returnTable.clearRows();

  for (int row = 0; row < inputTable.getRowCount(); row++){
    String rowValue = inputTable.getString(row, columnName);

    if (!isNullOrBlank(rowValue) && isNumeric(rowValue)){
      returnTable.addRow(inputTable.getRow(row));
    }
  }

  return returnTable;

}

But note that this code isn't necessarily better than your code. It's not any faster. And if you understood your code, then that's the most important thing. If it works, don't worry too much about making it "more elegant". Just move on to the next thing.