.NETGURU
Sort Based on Property.
Messages   Related Types
This message was discovered on ASPFriends.com 'aspngarchitecture' list.


Daniel Wilson
Hello,
A few days ago someone, Bryan? maybe, posted a slightly modified version
of the ECC design pattern called MCC. Well anyways, I want go over the
pattern again but basically it had a custom collection of a User Created
Class referred to as ObjectCollection. In it he suggested adding a method
Sort() that allowed objects to be sorted based on a property. How would
this function look (some sample code would be great :)
See the reason I am asking is that most examples I have seen have
special sort functions for EACH property or in my case I have an enum with
possible field name (property names) to sort on (i.e.
MyCollection.Sort(MyCollection.SortOn field) where SortOn is an enum inside
MyCollection Class.) However, in his pattern he has a general collection,
ObjectCollection, with ONE sort method that will sort on any arbitrary
property of the collected classes. I just don't see how one could do that.
Either A I read the pattern wrong or B I am missing something. I would
really appreciate it if Bryan or anyone else will help me out on this
matter.

Thanks in advance,
Daniel Wilson
Reply to this message...
 
    
Bryan Costanich
Part 3

#endregion

//========================================================================

//========================================================================
#region -= public properties =-

//---- SortPropertyName

public string SortPropertyName

{

get { return
m_strSortPropertyName; }

set { m_strSortPropertyName
= value; }

}

#endregion

//========================================================================

}

//========================================================================

#endregion

//========================================================================

}

//========================================================================
}
Reply to this message...
 
    
Bryan Costanich
Part 2

//========================================================================
#region -= public properties =-

//---- SortPropertyName

public string SortPropertyName

{

get { return
this.m_objComparer.SortPropertyName; }

}

//---- SortOrder

public SortOrders SortOrder

{

get { return this.m_objSortOrder; }

}

#endregion

//========================================================================

#endregion

//========================================================================

//========================================================================
#region -= internal helper classes =-

//========================================================================
protected internal sealed class PropertyComparer :
IComparer

{

//========================================================================
#region -= private declarations =-

private string m_strSortPropertyName;

#endregion

//========================================================================

//========================================================================
#region -= public methods =-

//========================================================================
/// <summary>

/// Performs a case-sensitive comparison
of two objects of the same type and returns a value indicating whether

/// one is less than, equal to or
greater than the other.

/// </summary>

/// <param name="x">The first object to
compare.</param>

/// <param name="y">The second object to
compare.</param>

/// <returns>-1 if a is less than b, 0
if equal, 1 if a is greater than b</returns>

public int Compare(object x, object y)

{

//---- if there is no
property to compare on, just peter out

if(m_strSortPropertyName =null || m_strSortPropertyName == "")

throw new
Exception("need a property to sort by");

//---- compare the
properties using the default comparer

return
Comparer.Default.Compare(GetPropertyValueRecursive(x,
m_strSortPropertyName),

GetPropertyValueRecursive(y, m_strSortPropertyName));

}

//========================================================================

#endregion

//========================================================================

//========================================================================
#region -= private/protected methods =-

//========================================================================
/// <summary>

/// Returns a property for a nested set
of objects such as object1.object2.object3.object4.property

/// </summary>

/// <param name="objectIn">the object to
look in</param>

/// <returns>the property of the last
object</returns>

private object
GetPropertyValueRecursive(object objectIn, string propertyName)

{

//---- declare vars

string[] strAryTypes propertyName.Split('.'); //split out the properties (RootObject, Child,
ChildChild, Property)

int intCurrentIndex = 0; //
start at the second type (object.xType1)

object objCurrentType objectIn; // start at the root object

//---- walk down the tree

while(intCurrentIndex <
strAryTypes.Length)

{

//---- get the
next type down the tree

objCurrentType objCurrentType.GetType().GetProperty(strAryTypes[intCurrentIndex]).GetValue(
objCurrentType, null);

//---- increment
the counter

intCurrentIndex++;

}

//---- now the
objCurrentType will have the last property

return objCurrentType;

}

//========================================================================
Reply to this message...
 
    
Chris Melvin
Bryan, Thanks for posting the custom Collection sort code. Works great when deriving from ArrayList.

Someone mentioned that the collection class could be derived from any class implementing ICollection, such as CollectionBase or DictionaryBase. I ran into some issues when deriving from any ICollection class that does not implement a Sort method. Sort is not a method in the ICollection interface.

Has anyone has tackled implementing a sort method in a CollectionBase or DictionaryBase derived collection class?

--------------------------------
From: Chris Melvin
Reply to this message...
 
    
Chris Melvin
Bryan, oops, my mistake, it does work with CollectionBase. Just have to change this.Sort and this.Reverse to this.InnerList.Sort and this.InnerList.Reverse.

Thanks again for posting the code!

--------------------------------
From: Chris Melvin
Reply to this message...
 
    
Bryan Costanich
Daniel,

Here is some robust code to do collection sorting. It will not only sort on
a property, but will also work for subitems, ie, sort on
Object.Object.Object.Property. It uses the internal ArrayList.Sort method
with a custom comparer. The sort method is a (n log2 n) algorithm so it's
pretty fast and scales well.

You'll notice that the custom collection is derived from an ArrayList, but
could just as well be derived from any object the implements ICollection.
In the pattern I mentioned ArrayList, but I need to update that as well
because it should be any ICollection object.

Additionally, the collection here is a generic one and not strongly typed.
If you wish to implement a strongly-typed collection (which are damn cool)
then you will probably want to create your own custom collection class and
derive from CollectionBase or DictionaryBase. In order to do it yourself you
are looking at a lot of code, and those objects already serve as a good
base. The last time I was working out at Microsoft I spoke to someone on
the .net team, I forget who, but they recommended deriving from those base
classes. I personally agree, the majority of the plumbing is already
present and tested and there will be no surprises.

You can download the entire project with the code at
http://codebox.wowzer.net/Code/CollectionSort.zip
<http://codebox.wowzer.net/Code/CollectionSort.zip> it has the collection
object and all the objects needed to test it. just unzip it into your
websites directory, create the folder as an app in IIS and hopefully it will
work.

Anyway, here is the code for the collection object itself:

PART 1 (have to split cause message is too long)

using System;

using System.Collections;

using System.Reflection;

namespace Sicily.Test.Classes

{

//========================================================================
/// <summary>

/// A generic item collection (not strongly typed) that enables
sort on properties of the objects in it.

/// </summary>

public class ItemCollection : ArrayList

{

//========================================================================
public enum SortOrders

{

None,

Ascending,

Descending

}

//========================================================================

//========================================================================
#region -= private declarations =-

protected PropertyComparer m_objComparer;

protected SortOrders m_objSortOrder;

#endregion

//========================================================================

//========================================================================
public ItemCollection()

{

m_objComparer = new PropertyComparer();

m_objSortOrder = SortOrders.None;

}

//========================================================================

//========================================================================
#region -= public methods =-

//========================================================================
/// <summary>

/// Sorts on a property on an item in the
collection. Works for nested properties as well.

/// <note>

/// Sorts ascending

/// </note>

/// </summary>

/// <param name="propertyName"></param>

public void Sort(string propertyName)

{

this.Sort(propertyName,
SortOrders.Descending);

}

//========================================================================

//========================================================================
/// <summary>

/// Sorts on a property on an item in the
collection. Works for nested properties as well.

/// </summary>

/// <param name="propertyName"></param>

public void Sort(string propertyName, SortOrders
sortOrder)

{

//---- set the sort order property

this.m_objSortOrder = sortOrder;

//---- set the property to sort by

m_objComparer.SortPropertyName propertyName;

//---- sort the collection

this.Sort(m_objComparer);

//---- if it's supposed to be
descending, reverse the array

if (sortOrder==SortOrders.Ascending)

{ this.Reverse(); }

}

//========================================================================

Have to split here cause message is to long.

-----Original Message-----
From: Daniel Wilson [mailto:Click here to reveal e-mail address]
Sent: Tuesday, July 09, 2002 1:19 PM
To: aspngarchitecture
Subject: [aspngarchitecture] Sort Based on Property.

Hello,

A few days ago someone, Bryan? maybe, posted a slightly modified version
of the ECC design pattern called MCC. Well anyways, I want go over the
pattern again but basically it had a custom collection of a User Created
Class referred to as ObjectCollection. In it he suggested adding a method
Sort() that allowed objects to be sorted based on a property. How would
this function look (some sample code would be great :)

See the reason I am asking is that most examples I have seen have
special sort functions for EACH property or in my case I have an enum with
possible field name (property names) to sort on (i.e.
MyCollection.Sort(MyCollection.SortOn field) where SortOn is an enum inside
MyCollection Class.) However, in his pattern he has a general collection,
ObjectCollection, with ONE sort method that will sort on any arbitrary
property of the collected classes. I just don't see how one could do that.
Either A I read the pattern wrong or B I am missing something. I would
really appreciate it if Bryan or anyone else will help me out on this
matter.

Thanks in advance,

Daniel Wilson

| [aspngarchitecture] member Click here to reveal e-mail address = YOUR ID
| http://www.asplists.com/asplists/aspngarchitecture.asp = JOIN/QUIT
| http://www.asplists.com/search = SEARCH Archives
Reply to this message...
 
    
Daniel Wilson
Hey brian I was using the code you sent me and after a little inspection
came across a part that I was hoping you or anyone could shed some light on
for me.
Here is the section:

//=========================================================================

/// <summary>

/// Sorts on a property on an item in the
collection. Works for nested properties as well.

/// <note>

/// Sorts ascending

/// </note>

/// </summary>

/// <param name="propertyName"></param>

public void Sort(string propertyName)

{

this.Sort(propertyName,
SortOrders.Descending);

}

//========================================================================

Notice how in the note section in the comments it states that this function
"sorts ascending" - Why would the internal implementation for the sort use
SortOrders.Descending . This doesn't seem right because for the users of
my collection ObjectCollection.Sort("ID", SortOrders.Descending) is the way
for them to sort my collection in accending order? Am I missing something?

Thanks

Daniel O Wilson
Reply to this message...
 
    
Bryan Costanich
No, you're not missing anything, I just made a typo.

Thanks for the catch.

-----Original Message-----
From: Daniel Wilson [mailto:Click here to reveal e-mail address]
Sent: Thursday, July 11, 2002 12:24 PM
To: aspngarchitecture
Subject: [aspngarchitecture] RE: Sort Based on Property.

Hey brian I was using the code you sent me and after a little inspection
came across a part that I was hoping you or anyone could shed some light on
for me.

Here is the section:

//=========================================================================

/// <summary>

/// Sorts on a property on an item in the
collection. Works for nested properties as well.

/// <note>

/// Sorts ascending

/// </note>

/// </summary>

/// <param name="propertyName"></param>

public void Sort(string propertyName)

{

this.Sort(propertyName,
SortOrders.Descending);

}

//========================================================================

Notice how in the note section in the comments it states that this function
"sorts ascending" - Why would the internal implementation for the sort use
SortOrders.Descending . This doesn't seem right because for the users of
my collection ObjectCollection.Sort("ID", SortOrders.Descending) is the way
for them to sort my collection in accending order? Am I missing something?

Thanks

Daniel O Wilson

| [aspngarchitecture] member Click here to reveal e-mail address = YOUR ID
| http://www.asplists.com/asplists/aspngarchitecture.asp = JOIN/QUIT
| http://www.asplists.com/search = SEARCH Archives
Reply to this message...
 
 
System.Collections.ArrayList
System.Collections.CollectionBase
System.Collections.Comparer
System.Collections.DictionaryBase
System.Collections.ICollection
System.Collections.IComparer
System.Exception
System.Object
System.Windows.Forms.SortOrder




ExamGuru IT Solutions - .Net Guru is owned and operated by ExamGuru, Inc., the man behind .Net Guru. If you're in the market for bespoke software or software consultancy, why not get him and his highly trained team to help? - www.examguru.net/ITCertification
Ad


Need Dot Net Interview Questions?
Ask ExamGuru, Inc. for advice and help on Passing .Net Interviews
.Net Projects
Best-of-breed application framework for .NET projects, developed by ExamGuru, Inc. and ExamGuru IT
Free .net Help
Commission ExamGuru, Inc. and his team for your next bespoke software project
FogBUGZ
The only bug tracking system carefully crafted with one goal in mind: helping teams create great software.
Awesome Tools
If you don't know about these, you're missing out... IT Certification Questions
IT Interview Questions
Free Oracle 10g Training
MCSE Boortcamp
Cisco Study Guides
Cheap Study Guides
Exact Questions
Dot Net Interview Questions
Oracle OCP
Cheap Travel
Designer Perfumes - Wholesale Prices
Free Programming Tutorials
 
ExamGuru IT Solutions - .Net Guru is owned and operated by ExamGuru, Inc., the man behind .Net Guru. If you're in the market for bespoke software or software consultancy, why not get him and his highly trained team to help? - www.examguru.net/ITCertification
 Copyright © ExamGuru, Inc. 2001-2006
Contact Us - Terms of Use - Privacy Policy - www.dot-net-guru.com - www.examguru.net - www.oraclesource.net - www.itinterviews.net - www.examguru.net/ITCertification