Sorting An Array Using
By Scott Mitchell
The .NET Framework makes it a cinch for developers to sort arrays by including a static method in the
Sort(). In its simplest form the
Sort()method accepts a single input parameter - the one-dimensional array to sort - and sorts the array. This implementation of the
Sort()method works well when the contents in the array implement the
IComparableinterface. (All of the primitive .NET types - Integer, Double, String, etc. - implement the
But what if you have an array of items that do not implement the
For example, in a previous article, Displaying the Files in a Directory
using a DataGrid, the
GetFiles() method was used to retrieve
an array of
FileInfo instances. This array was then bound to a DataGrid. (See
this live demo to see the files from the
directory displayed in a DataGrid.)
Imagine, though, that we wanted to sort the array of
FileInfo instances before
binding it to the DataGrid. The
FileInfo class does not implement
so we can't just pass the array of
FileInfos into the
Furthermore, even if we could, this might sort the array by the file name, whereas we might want to
sort it by the file size.
Fortunately, the .NET Framework is flexible enough to allow for custom sorting of any object in an
array. In order to sort arrays whose elements do not implement
IComparable, we must
create a class that implements
IComparer, which specifies how the array should be sorted.
In this article we will first look at sorting arrays that contain elements that implement
Then we will see how to create a class that implements
IComparer so that we can sort arrays
that do not contain elements that implement
IComparable. Finally, we will look at how
to enhance the live demo presented in Displaying the Files in a Directory
using a DataGrid to allow for displaying the files in a directory in a sortable DataGrid.
An Introduction to Interfaces
An interface is a concept common to object-oriented programming that, if applies to a particular class, indicates that the class must contain a certain set of methods. That is, with an interface, you specify a number of methods, including their name, their return type, and their input parameters. The interface does not contain any code for the methods - rather, it just has the method's declaration present. Then, when you indicate that a class implements the interface, this class must contain, at minimum, the methods outlined in the interface, providing the body of these methods.
Think of an interface as a contract. When a class implements an interface, it is saying to the world, "I promise to have the methods outlined in the interface definition." The benefit of classes implementing an interface, is that other developers can create libraries that accept any class instance, so long as it implements a given interface.
In addition to developers being able to create their own interfaces, the .NET Framework provides a
number of built-in interfaces that its classes use. In this article, we'll look at two interfaces,
IComparer. When a class implements
the class is essentially saying to the world, "Given an instance of myself, this instance can compare
itself to another instance, indicating if its 'less than', 'greater than', or 'equal' to the other instance."
When a class implements the
Comparer interface, the class is saying to the world, "I am a
class that can make comparisons about instances of another class." In this article we'll see how
both of these interfaces help make sorting arrays easy with .NET!
Sorting an Array Whose Elements Implement
Arrays that consist of elements that implement the
IComparableinterface can be sorted using the
Sort()method via the following syntax:
Array.Sort(ArrayName). Classes that implement the
IComparableinterface guarantee that they have a method named
CompareTo()that takes in a single parameter, an Object, and returns an Integer. The Integer value indicates how the existing class instance and the object passed into it compare to one another. A value of 0 indicates that they are equal, a value less than zero indicates that the class instance is less than the passed in object, and a value greater than zero indicates that the class instance is greater than the passed in object.
Behind the scenes, the
Array.Sort(ArrayName) method performs a
QuickSort on the
elements in the array ArrayName, using the
CompareTo() method to compare the
elements in the array to one another.
The primitive data types in the .NET Framework all implement the
Therefore, if you have an array of this type, you can use the
approach to sort an array of these types, as the following example and live demo
Sorting an Array Whose Elements Do Not Implement
In an earlier article of mine, Displaying the Files in a Directory using a DataGrid, I looked at how to use the DataGrid to display a list of files from a directory. The
GetFiles()method was used to retrieve an array of
FileInfoinstances that were then bound to a DataGrid (see this live demo). After publishing this article, I received feedback from a number of users who wondered how one could display the list of files in a DataGrid, and also allow for the DataGrid to be sortable.
In order to create a sortable DataGrid, we first need to be able to sort the array of
instances returned by the
GetFiles() method. However,
FileInfo class does not implement the
IComparable interface, so therefore
it is not possible to use the
Array.Sort(ArrayName) approach. Rather, we have to
create a new class, one that implements
IComparer. This new class will have a single job:
FileInfo instances, the class should be able to compare the two, and return
an integer value indicating if the first
FileInfo instance is less than, equal to, or
greater than the second.
Of course, what does it mean for a
FileInfo instance to be "less than" another? Does it
mean that the first
FileInfo instance's file name comes before the second's alphabetically?
Does it mean that the first
FileInfo instance's file size is less than the second's?
Clearly, any of these interpretations is valid. Furthermore, since in displaying the files in a
DataGrid we are display their file name, file size, and last written date, it should be possible to
FileInfo instances by their file name, file size, and last write date.
For the time being, imagine that we already have created a class that implements
and allows for sorting by the
FileInfo's file name, size, or last written date. Once
we have this completed, we can sort the array of
FileInfos by calling the
method like so:
Array.Sort(ArrayName, InstanceOfComparingClass). Here, the
InstanceOfComparingClass is an instance of the class that implements
The main task ahead of us now is creating the class that can compare
We'll look at creating this class in Part 2.