We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › Sort objects by int()
Page Index Toggle Pages: 1
Sort objects by int() (Read 1414 times)
Sort objects by int()
Apr 19th, 2010, 8:57am
 
I have arrays of objects that i'm sorting by different means, here is the comparator that I have been using to sort the objects by when sorting by a string attribute:
Code:
class CompareEvent implements Comparator
{
 public int compare(Object o1, Object o2)
 {
   return ((OBJECT TYPE) o1).STRING ATTRIBUTE.compareTo(((OBJECT TYPE) o2).STRING ATTRIBUTE);
 }
}


Is there an equivalent java function to 'compareTo' compare these objects by an int/float value rather than a string?

I know sort() works with arrays of ints/floats, but I haven't managed to find anything about using sort() with objects.

I've been trying to work around it by converting my floats into strings, but negative values confuse things when sorting alphabetically:/

Thanks!


Re: Sort objects by int()
Reply #1 - Apr 19th, 2010, 9:07am
 
To compare 2 integers called i0 and i1 use

(new Integer(i0)).compareTo(new Integer(i1))

for floats f0 & f1

(new Float(f0)).compareTo(new Float(f1))

should work OK

Re: Sort objects by int()
Reply #2 - Apr 19th, 2010, 9:08am
 
Hi Ladle

I still have to answer your private mail, I think about it everyday but beside short answers on the forum, I find little time for computing currently (might be better this week...).

It is actually simpler to compare numerical values:
Code:
class CompareEvent implements Comparator
{
 public int compare(Object o1, Object o2)
 {
   return int(((OBJECT TYPE) o1).FLOAT ATTRIBUTE - ((OBJECT TYPE) o2).FLOAT ATTRIBUTE);
 }
}
Re: Sort objects by int()
Reply #3 - Apr 19th, 2010, 9:33am
 
Thank you both for such speedy responses! No worries PhiLo Wink
Re: Sort objects by int()
Reply #4 - Apr 22nd, 2010, 4:35am
 
I've found a couple of strange things occuring with this sort, 90% of the time it works, but a few values are appearing in the wrong place Shocked

This is the code for the sketch I'm testing it with:
www.samhumphrey.co.uk/testArea/uniSortCode.rtf

& here is the spreadsheet that the code is reading:
www.samhumphrey.co.uk/testArea/UniversityFunding10.xls

It produces a file like this:
www.samhumphrey.co.uk/testArea/sortOutput.pdf

I've looked through the spreadsheet & there're no spaces etc in front of the number values that might have set it off, so I'm not quite sure where to look!
Re: Sort objects by int()
Reply #5 - Apr 22nd, 2010, 7:30am
 
Not sure what is going on, but if I sort with Excel your table on the "Percentage change in total grant", I get the same order as in the PDF...

There are points you can improve in your code, BTW:
- There is redundancy between your multiple array of data (with fixed length defined in code!) and the array list of university data objects.
- You create each object twice, dropping the first one.
- You should let the class to choose the color in the constructor.
And some others.
Here is my version, producing a result close of your, but alas still incorrect on the sort side...
Code:
//SOURCE: http://www.hefce.ac.uk/finance/recurrent/2010/?o=2.
import processing.pdf.*;
import de.bezier.data.*;
XlsReader reader;
PFont font;

ArrayList uniArrayList;

float spacePerUni;


class CompareNames implements Comparator
{
public int compare(Object o1, Object o2)
{
return ((UniversityObject) o1).uniName.compareTo(((UniversityObject) o2).uniName);
}
}


class CompareFloats implements Comparator
{
public int compare(Object o1, Object o2)
{
return (int)(((UniversityObject) o1).perChangeFloat - ((UniversityObject) o2).perChangeFloat);
}
}


void setup(){
size(400, 700, PDF, "file.pdf");
background(255);
font = createFont("Arial", 4);
textFont(font);
uniArrayList = new ArrayList();//create an empty list.
reader = new XlsReader( this, "UniversityFunding10.xls" );
int numCounter = reader.getFirstRowNum() + 1;//finds first cell with content. Skip title
int lastCell = reader.getLastRowNum();
boolean bReadNext = true;
while (numCounter <= lastCell) // Never reach it if we have the "Total" cell.
{
String university = reader.getString(numCounter, 0);
if (university.equals("Total"))
{
break;
}
int totalFunding = reader.getInt(numCounter, 1);
int wideningParticipation = reader.getInt(numCounter, 2);
int totalResearch = reader.getInt(numCounter, 3);
int recurrentGrant = reader.getInt(numCounter, 6);
float percentageChange = reader.getFloat(numCounter, 7);

uniArrayList.add(new UniversityObject(numCounter, university, totalFunding,
wideningParticipation, totalResearch, recurrentGrant, percentageChange, 0));
numCounter++;
}
spacePerUni = (height-200)/uniArrayList.size();//finds how much vertical space for each uni.

println(uniArrayList.size()+" arraylist '10 size");
}//end of setup.


void draw(){
noLoop();

Collections.sort(uniArrayList, new CompareFloats());

for(int i=0; i<uniArrayList.size(); i++){
UniversityObject uo = (UniversityObject) uniArrayList.get(i);
uo.display(i);
}

println("Done");
exit();
}//end of draw.


class UniversityObject {//define my class.

int num;//no. of uni in list..
String uniName;//class variables.
int totalFundingInt;
int wideningParInt;
int totalResearchInt;
int recGrantInt;
float perChangeFloat;
color c;
int yearsBack;

UniversityObject(int tempNum, String tempUniName, int tempTotalFundingInt, int tempWideningParInt, int tempTotalResearchInt, int tempRecGrantInt, Float tempPerChangeFloat, int tempYearsBack) {// constructor.
num = tempNum;
uniName = tempUniName;
totalFundingInt = tempTotalFundingInt;
wideningParInt = tempWideningParInt;
totalResearchInt = tempTotalResearchInt;
recGrantInt = tempRecGrantInt;
perChangeFloat = tempPerChangeFloat;
if (perChangeFloat > 0)
{
c = color(0, 0, 255);
}
else
{
c = color(255, 0, 0, 100);
}
yearsBack = tempYearsBack;
}

void display(int i) {//function of the ojects created by the class.
num = i;
fill(c);
noStroke();
rect(width/2, 21 + num*5 - spacePerUni/2, perChangeFloat*10, spacePerUni);
textAlign(LEFT);
textSize(4);
if(perChangeFloat>0){
text(uniName + " " + perChangeFloat +"%", (width/2)+(perChangeFloat*10)+5, 22+(num*5));
}else{
fill(255, 0, 0);
text(uniName + " " + perChangeFloat +"%", (width/2)+5, 22+(num*5));
}
}
}

Will investigate more.
Re: Sort objects by int()
Reply #6 - Apr 22nd, 2010, 7:34am
 
Aha, got it!
My advice above was too naive... When difference between the floats is below 1, it returns 0, telling the floats are identical. The sort order of identical values is semi-random, depending on algorithm.
We have to round at higher level.
Code:
class CompareFloats implements Comparator
{
public int compare(Object o1, Object o2)
{
return int(1000.0*(((UniversityObject) o1).perChangeFloat - ((UniversityObject) o2).perChangeFloat));
}
}
works...
Re: Sort objects by int()
Reply #7 - Apr 22nd, 2010, 11:31am
 
Glad it wasnt just me! Thank you Grin- Yes I began the sketch by making an array of objects befre realising that it should be an arrayList, haven't tidied up yet:)

How did you work out that final revision of the sort function? - I had a look about but didnt find anything that seemed relevant.

Also, what does this do? - "boolean bReadNext = true;"

L.
Re: Sort objects by int()
Reply #8 - Apr 22nd, 2010, 10:17pm
 
What sort function? If you mean CompareFloat, you have to know such function must return a negative value if o1 is smaller than o2, a positive one otherwise, and 0 if they are equal.

And the bReadNext was meant to be used as condition for the while loop but I preferred to guard against the absence of "Total" cell (the actual stop condition) to avoid infinite loop... So finally I didn't use it, just drop it.
Page Index Toggle Pages: 1