Home > ASP.NET, c# > Sorting and Filtering Objects within Generic Lists

Sorting and Filtering Objects within Generic Lists

I started working with Generics about 6 months ago. The main reason is because I just now started using custom objects for just about everything in my applications. It was a bit of a pain in the rear when I found out the GridView sort didn’t ‘just work’ when you bound it to a generic collection like the way it does when you bind it to a dataset. The other caveat I found was that it was more difficult to filter. I couldn’t just use DataViews or a Select on the table in the DataSet. I had to create some new functionality for filtering and sorting for generics. Here are my examples.

This first method takes a generic list as a parameter and passes the same list back, but sorted. Note that this requires the Comparison Generic Delegate listed down the page further. Substitute in your own custom object for my “ImageObject”:
// Pass in a generic list of objects (ImageObjects in my case) you want sorted, and by what property you want it sorted.
public List<ImageObject> sortImageList(List<ImageObject> ImageList, string sortExpression)
{
    SortExp = sortExpression;

    if (sortExpression != string.Empty)
    {
        Comparison<ImageObject> compare;
        compare = new Comparison<ImageObject>(CompareBy);
        ImageList.Sort(compare);
    }

    return ImageList;
}

This version does the same thing as the last, but, instead of passing in a List, it grabs one from the data access layer, sorts it, then returns it. Note that this requires the Comparison Generic Delegate listed down the page further. Substitute in your own custom object for my “ImageObject”:
public List<ImageObject> sortImageList(int OwnerID, UserData.ImageLookupType LookupType, bool sort, string sortExpression)
{
    List<ImageObject> list = _UserData.getImageList(OwnerID, LookupType);

    SortExp = sortExpression;

    if (sortExpression != string.Empty)
    {
        Comparison<ImageObject> compare;
        compare = new Comparison<ImageObject>(CompareBy);
        list.Sort(compare);
    }

    return list;
}

Here is the Comparison Generic Delegate that does our object comparison and bubbles them into order. Substitute your own objects’ property names:
private int CompareBy(ImageObject Image1, ImageObject Image2)
{
    int iRet = 0;
    switch (_SortExp)
    {
        case “Name”:
        case “Name ASC”:
            iRet = Image1.Name.CompareTo(Image2.Name);
            break;
        case “Name DESC”:
            iRet = Image2.Name.CompareTo(Image1.Name);
            break;
        case “DateUploaded”:
        case “DateUploaded ASC”:
            iRet = Image1.DateUploaded.CompareTo(Image2.DateUploaded);
            break;
        case “DateUploaded DESC”:
            iRet = Image2.DateUploaded.CompareTo(Image1.DateUploaded);
            break;
        case “Views”:
        case “Views ASC”:
            iRet = Image1.Views.CompareTo(Image2.Views);
            break;
        case “Views DESC”:
            iRet = Image2.Views.CompareTo(Image1.Views);
            break;
    }

    return iRet;
}

This leaves us with filtering. In this first method, you pass in a full list and return a single object based on the filter criteria:
public ImageObject FilterByImageID(List<ImageObject> ImageList, int ImageID)
{
    Predicate<ImageObject> filterByImageID;
    ImageIDFilter filter = new ImageIDFilter(ImageID);
    filterByImageID = new Predicate<ImageObject>(filter.FilterByImageID);
    return ImageList.Find(filterByImageID);
}

The ImageIDFilter is the name of teh class I created to do the actual
comparison of the object in the lists property to the criteria I’ve
passed in:
private class ImageIDFilter
{
    private int _ImageID;

    public bool FilterByImageID(ImageObject Image)
    {
        return (Image.ImageID == _ImageID);
    }

    public ImageIDFilter(int ImageID)
    {
        _ImageID = ImageID;
    }
}

There is also a shorthand version of this same method:
ImageObject io = myGenericList.Find(delegate(ImageObject image) { return image.Image == _ImageID; });

The latter would be much easier for simple filters, whereas the former best for more complex filtering.

Categories: ASP.NET, c# Tags:
  1. No comments yet.
  1. No trackbacks yet.