By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,939 Members | 1,559 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,939 IT Pros & Developers. It's quick & easy.

How to sort this array

P: n/a
Hello,

Persons is a hashtable which I convert to an array.

Person[] aPerson = new Person[Persons.Count];
Persons.Values.CopyTo( aPerson, 0 );

Now I can access the person items like aPerson[3].name or
aPerson[3].birthdate.

How can I sort all the array items based on the birthdate?
So that the first name with the birthdate can be found here aPerson[0].name
and aPerson[0].birthdate.

Thanks!

Nov 15 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Arjen <bo*****@hotmail.com> wrote:
Persons is a hashtable which I convert to an array.

Person[] aPerson = new Person[Persons.Count];
Persons.Values.CopyTo( aPerson, 0 );

Now I can access the person items like aPerson[3].name or
aPerson[3].birthdate.

How can I sort all the array items based on the birthdate?
So that the first name with the birthdate can be found here aPerson[0].name
and aPerson[0].birthdate.


Use Array.Sort with an IComparer which is able to compare instances of
Person by birth date.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #2

P: n/a
Okay, that for your answer.
But I don't get it to work.

I also found a document how to sort a hashtable...
http://msdn.microsoft.com/library/de...rp01212002.asp
But I don't know how to work with it.

Can you give me a little sample code?

Thanks!

"Jon Skeet [C# MVP]" <sk***@pobox.com> schreef in bericht
news:MP************************@msnews.microsoft.c om...
Arjen <bo*****@hotmail.com> wrote:
Persons is a hashtable which I convert to an array.

Person[] aPerson = new Person[Persons.Count];
Persons.Values.CopyTo( aPerson, 0 );

Now I can access the person items like aPerson[3].name or
aPerson[3].birthdate.

How can I sort all the array items based on the birthdate?
So that the first name with the birthdate can be found here aPerson[0].name and aPerson[0].birthdate.


Use Array.Sort with an IComparer which is able to compare instances of
Person by birth date.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #3

P: n/a
This: Okay, that for your answer.
Must be: ...thanks...

What I don't get is...
The hashtable has object... how can I sort the hashtable based on one object
item?

Thanks!
Arjen


"Arjen" <bo*****@hotmail.com> schreef in bericht
news:bv**********@news1.tilbu1.nb.home.nl...
Okay, that for your answer.
But I don't get it to work.

I also found a document how to sort a hashtable...
http://msdn.microsoft.com/library/de...rp01212002.asp But I don't know how to work with it.

Can you give me a little sample code?

Thanks!

"Jon Skeet [C# MVP]" <sk***@pobox.com> schreef in bericht
news:MP************************@msnews.microsoft.c om...
Arjen <bo*****@hotmail.com> wrote:
Persons is a hashtable which I convert to an array.

Person[] aPerson = new Person[Persons.Count];
Persons.Values.CopyTo( aPerson, 0 );

Now I can access the person items like aPerson[3].name or
aPerson[3].birthdate.

How can I sort all the array items based on the birthdate?
So that the first name with the birthdate can be found here aPerson[0].name and aPerson[0].birthdate.


Use Array.Sort with an IComparer which is able to compare instances of
Person by birth date.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Nov 15 '05 #4

P: n/a
Arjen <bo*****@hotmail.com> wrote:
This: Okay, that for your answer.
Must be: ...thanks...

What I don't get is...
The hashtable has object... how can I sort the hashtable based
on one object item?


You said before that you didn't want to sort your hashtable - you
wanted to sort an array you'd copied from the hashtable. Sorting a
hashtable doesn't make any sense, as hashtables aren't really ordered.

So, when you've copied your hashtable contents to an array (eg
myPersonArray) you'd then call

Array.Sort (myPersonArray, new BirthDateComparer());

where BirthDateComparer would be a class which implements IComparer by
casting each of the arguments of CompareTo to a Person, then comparing
their birth dates.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #5

P: n/a
Hi,
where BirthDateComparer would be a class which implements IComparer by
casting each of the arguments of CompareTo to a Person, then comparing
their birth dates.
Can you show me how this looks like?

Thanks!

"Jon Skeet [C# MVP]" <sk***@pobox.com> schreef in bericht
news:MP************************@msnews.microsoft.c om... Arjen <bo*****@hotmail.com> wrote:
This: Okay, that for your answer.
Must be: ...thanks...

What I don't get is...
The hashtable has object... how can I sort the hashtable based
on one object item?


You said before that you didn't want to sort your hashtable - you
wanted to sort an array you'd copied from the hashtable. Sorting a
hashtable doesn't make any sense, as hashtables aren't really ordered.

So, when you've copied your hashtable contents to an array (eg
myPersonArray) you'd then call

Array.Sort (myPersonArray, new BirthDateComparer());

where BirthDateComparer would be a class which implements IComparer by
casting each of the arguments of CompareTo to a Person, then comparing
their birth dates.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #6

P: n/a
Arjen <bo*****@hotmail.com> wrote:
where BirthDateComparer would be a class which implements IComparer by
casting each of the arguments of CompareTo to a Person, then comparing
their birth dates.


Can you show me how this looks like?


It would be *something* like:

public class BirthDateComparer : IComparer
{
public void Compare(object o1, object o2)
{
Person p1 = (Person) o1;
Person p2 = (Person) o2;

DateTime d1 = p1.BirthDate;
DateTime d2 = p2.BirthDate;

return DateTime.Compare (d1, d2);
}
}

(But I haven't compiled and tested the above.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #7

P: n/a
Hi,

Thanks!
With a little change...
public class BirthDateComparer : IComparer
{
public void Compare(object o1, object o2)
{
Person p1 = (Person) o1;
Person p2 = (Person) o2;

DateTime d1 = p1.BirthDate;
DateTime d2 = p2.BirthDate;

return DateTime.Compare (d1, d2);
}
}
Void must be an int because DateTime.Compare returns an int.

Arjen

"Jon Skeet [C# MVP]" <sk***@pobox.com> schreef in bericht
news:MP************************@msnews.microsoft.c om... Arjen <bo*****@hotmail.com> wrote:
where BirthDateComparer would be a class which implements IComparer by
casting each of the arguments of CompareTo to a Person, then comparing
their birth dates.


Can you show me how this looks like?


It would be *something* like:

public class BirthDateComparer : IComparer
{
public void Compare(object o1, object o2)
{
Person p1 = (Person) o1;
Person p2 = (Person) o2;

DateTime d1 = p1.BirthDate;
DateTime d2 = p2.BirthDate;

return DateTime.Compare (d1, d2);
}
}

(But I haven't compiled and tested the above.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #8

P: n/a
Arjen <bo*****@hotmail.com> wrote:
Void must be an int because DateTime.Compare returns an int.


Doh - and because that's the whole point of the method, too :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #9

P: n/a
Hi,

I did this class a time ago to sort any IList, it can be used to sort any
class without any requeriment of the class itself, I use reflection to get
the value of the property passed to the constructor and the only thing that
you need to assure is that the Property type you are sorting on implement
IComparable

This is how you use it:

//Create the IComparer
ClassSorter sorter = new ClassSorter( "BirthDate", SortByType.Property,
SortDirection.Ascending);
//This sort the list using the IComparer sorter
passengerList.Sort( sorter);
Here is the code, it's extremely simple, all you need to especify is the
name of the property you will sort by, a note is is that it can be a complex
object and you can go deeper like :
ClassSorter sorter = new ClassSorter( "Spouse.BirthDate",
SortByType.Property, SortDirection.Ascending);

There you are sorting a list of Passenger, by using the Property BirthDate
of the property Spouse ( I hope you followed me :) )

The class implementation is very simple, it basically consist of two
methods, the required IComparer.Compare method:
public int Compare(object x, object y)
{
return Compare( x, y, sortBy);
}

And the "real" Compare method, that using reflection get the value of the
property named on the constructor and compare both:

int Compare( object x, object y, string comparer)
{
//First see if the comparer is a complex expression, if so go recursive
until get the final simple type
if ( comparer.IndexOf( ".") != -1 )
{
//split the string
string[] parts = comparer.Split( new char[]{ '.'} );
// Call recursively
// NOTE:
// I do remember from my Programming class that a Tail recursion can be
implemented iteratively, but it will performed on the next adventure :)
return Compare( x.GetType().GetProperty( parts[0]).GetValue(x, null) ,
y.GetType().GetProperty( parts[0]).GetValue(y, null) , parts[1]
);
}
else
{
IComparable icx, icy;
//Get the value of both property
icx =
(IComparable)x.GetType().GetProperty( comparer).GetValue(x, null);
icy =
(IComparable)y.GetType().GetProperty( comparer).GetValue(y, null);

//Hack, if it's a string do a case insensitive comparision
if ( x.GetType().GetProperty(comparer).PropertyType ==
typeof(System.String) )
{
icx = (IComparable) icx.ToString().ToUpper();
icy = (IComparable) icy.ToString().ToUpper();
}

// See if descending or ascending
if(this.sortDirection == SortDirection.Descending)
return icy.CompareTo(icx);
else
return icx.CompareTo(icy);
}

}
As you can see it's a pretty simple class, but it does solve a big problem.
here is the code in full, if you have any comment just send me an email
Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

////////////////********************************* CODE START
****************////////////////
public enum SortByType
{
Method = 0,
Property = 1
}

public enum SortDirection
{
Ascending = 0,
Descending = 1
}

/// <summary>
/// Summary description for ClassSorter.
/// </summary>
public class ClassSorter: IComparer
{
protected string sortBy;
protected SortByType sortByType;
protected SortDirection sortDirection;
#region Constructors
public ClassSorter(string sortBy, SortByType sortByType, SortDirection
sortDirection)
{
this.sortBy = sortBy;
this.sortByType = sortByType;
this.sortDirection = sortDirection;
}
#endregion

int Compare( object x, object y, string comparer)
{
if ( comparer.IndexOf( ".") != -1 )
{
//split the string
string[] parts = comparer.Split( new char[]{ '.'} );
return Compare( x.GetType().GetProperty( parts[0]).GetValue(x, null) ,
y.GetType().GetProperty( parts[0]).GetValue(y, null) , parts[1]
);
}
else
{
IComparable icx, icy;
icx =
(IComparable)x.GetType().GetProperty( comparer).GetValue(x, null);
icy =
(IComparable)y.GetType().GetProperty( comparer).GetValue(y, null);

if ( x.GetType().GetProperty(comparer).PropertyType ==
typeof(System.String) )
{
icx = (IComparable) icx.ToString().ToUpper();
icy = (IComparable) icy.ToString().ToUpper();
}

if(this.sortDirection == SortDirection.Descending)
return icy.CompareTo(icx);
else
return icx.CompareTo(icy);
}

}

public int Compare(object x, object y)
{
return Compare( x, y, sortBy);
}

}

////////////////********************************* CODE END
****************////////////////
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Arjen <bo*****@hotmail.com> wrote:
where BirthDateComparer would be a class which implements IComparer by
casting each of the arguments of CompareTo to a Person, then comparing
their birth dates.


Can you show me how this looks like?


It would be *something* like:

public class BirthDateComparer : IComparer
{
public void Compare(object o1, object o2)
{
Person p1 = (Person) o1;
Person p2 = (Person) o2;

DateTime d1 = p1.BirthDate;
DateTime d2 = p2.BirthDate;

return DateTime.Compare (d1, d2);
}
}

(But I haven't compiled and tested the above.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.