Comparing objects

P

paolo.ponzano

Hello,

I've to implement a IComparer in order to sort an arraylist.
I've used reflection to get the object I need to sort, at the moment
I'm using the following piece of code:

public int Compare(object x, object y)
{
int i = 0;

object c = getIvar(x, listaOrdinamento[0].ToString());
object d = getIvar(y, listaOrdinamento[0].ToString());

i = c.ToString().CompareTo(d.ToString());

return i;
}

is there better way of doing that?
Have I to check the type of c and d and do the compare based on type?
or does the .ToString() cover all the cases?

Thanks

Bests

Paolo
 
S

sloan

Look at this idea:

I'm not sure if it'll help or not:




using System;
using System.Collections;


namespace MyApplication.Comparers
{


internal sealed class EmployeeComparer : IComparer
{
private EmployeeSortColumns m_sortValue = EmployeeSortColumns.None ;

public enum EmployeeSortColumns
{
None = 0 , LastName = 1 , FirstName = 2 , LastNameAndFirstName = 3
}

public EmployeeComparer(EmployeeSortColumns sortValue)
{
m_sortValue = sortValue;
}

public int Compare(object x,object y)
{
switch(m_sortValue)
{

case EmployeeSortColumns.None :
return 0;


case EmployeeSortColumns.FirstName :

return ((Employee)x).FirstName .CompareTo(((Employee )y).FirstName );
//break;
case EmployeeSortColumns.LastName :


return ((Employee)x).LastName.CompareTo(((Employee )y).LastName );

case LastNameAndFirstName :

string xValue = ((Employee)x).LastName + ((Employee)x).FirstName;
string yValue = ((Employee)y).LastName + ((Employee)y).FirstName;

return xValue.CompareTo(yValue);



default:
return ((Employee)x).LastName .CompareTo(((Employee )y).LastName );
// break;
}
}
}


}
 
?

=?ISO-8859-1?Q?Tobias_Schr=F6er?=

Hi,

Hello,

I've to implement a IComparer in order to sort an arraylist.
I've used reflection to get the object I need to sort, at the moment
I'm using the following piece of code:

public int Compare(object x, object y)
{
int i = 0;

object c = getIvar(x, listaOrdinamento[0].ToString());
object d = getIvar(y, listaOrdinamento[0].ToString());

i = c.ToString().CompareTo(d.ToString());

return i;
}

is there better way of doing that?
Have I to check the type of c and d and do the compare based on type?
or does the .ToString() cover all the cases?

Thanks

Bests

Paolo

that depends on the objects you want to compare. Are they of the same
type or base on the same type, other that Object? If so, just make this
type implement the IComparable interface and compare the two objects.

For comparison, you should know, by what attribute you want to compare.
Is it something like a name, a size, a whatever? The ToString member is
not very good for comparison. I'm not sure, what the default output for
Object.ToString actually is, but I would not use it for a comparison.
Most probably you will end up in an unsatisfying sorting.

Tobi
 
P

paolo.ponzano

Thanks for your fast answer,

sloan : I've tought about switching, but there's one more problem,
I've to sort based on an arraylist of 3 element (multiple-sort array)
and I need it to be as much generic as possible since it will be
applied to different object, not only to one. I'll pass the sort-rule
ArrayList externally.

Tobias : the comparison is on item of the same type, for example I may
have an arraylist of Employer where once I order with LastName,
FirstName, BirthDate, last time with a different order

Thanks a lot guys!
 
?

=?ISO-8859-1?Q?Tobias_Schr=F6er?=

Thanks for your fast answer,

sloan : I've tought about switching, but there's one more problem,
I've to sort based on an arraylist of 3 element (multiple-sort array)
and I need it to be as much generic as possible since it will be
applied to different object, not only to one. I'll pass the sort-rule
ArrayList externally.

Tobias : the comparison is on item of the same type, for example I may
have an arraylist of Employer where once I order with LastName,
FirstName, BirthDate, last time with a different order

Then this is easy. Just let let the type Employer implement the
IComparable interface:

<code>

class Employer : IComparable {
// ...
public int CompareTo(object obj) {
// check not null and same type
if (obj == null || !(obj is Employer)) {
throw ArgumentException();
}

// compare by Name
return this.Name.CompareTo(((Employer)obj).Name);
}
}

</code>

You should adjust the comparison to your requirements ;)

If you want to sort the list of Employers (List employerList), just call
employerList.Sort();
The method will automatically use the Employer.CompareTo member for
comparison.
 
J

james.curran

class FirstNameAscending : IComparer
{
public Compare(object x, object y)
{
Employer lhs = x as Employer;
Employer rhs = y as Employer;
// Add error handling for if either lhs or rhs is null here.
return lhs.FirstName.CompareTo(rhs.FirstName);
}
}

ArrayList Employers = ......
IComparer sortby = null;
switch (....)
{
case 1: sortby = new FirstNameAscending(); break;
case 5: sortby = new LastNameDescending(); break;
// etc.
}

Employers.Sort(sortby);

I'm not sure what you mean by "arraylist of 3 element (multiple-sort
array) ".
I'm gonna guess that you be getting something like:
string[] SoryBy = {"LastName" , "FirstName", "BirthDate"}

This complicates it a bit, but the basic principle above remains. You
do not want to decide how you will be sorting the items inside the
Compare. That should be done *once* beforehand.

class class FirstNameAscending : IComparer
{
IComparer otherwise;
public FirstNameAscending( IComparer pComparer)
{ otherwise = pComparer; }

public int Compare(object x, object y)
{
Employer lhs = x as Employer;
Employer rhs = y as Employer;
int cmp = lhs.FirstName.CompareTo(rhs.FirstName);
if (cmp != 0 || otherwise == null)
return cmp;
else
return otherwise.Compare(x, y);
}

IComparer sortby = new LastNameAscending(new
FirstNameAscending(new BirthDateDescending(null)))
employers.Sort(sortby);

or more generally:
string[] SortByStr = {"LastName" , "FirstName", "BirthDate"}
IComparer sortby = null;
for(i=SortByStr.Length-1; i>=0; --i)
{
switch (SortByStr)
{
case "FirstName":
sortby = new FirstNameAscending(sortby);
break;
case "LastName":
sortby = new LastNameAscending(sortby);
break;
// etc.
}
}
employers.Sort(sortby);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top