I have this class:
public class StatInfo
{
public string contact;
public DateTime date;
public string action;
}
then I have a list of StatInfo, but I'm not sure how to sort it according to the date field. Should I use the sort method? Should I create my own?
var _allStatInfo = new List<StatInfo>();
// adding lots of stuff in it
_allStatInfo.SortByDate???
What is the best way of doing this without having to write tons of code (if possible)?
Thanks
sort() method to sort a list of objects using some examples. By default, the sort() method sorts a given list into ascending order (or natural order). We can use Collections. reverseOrder() method, which returns a Comparator, for reverse sorting.
Sorting in C# In C#, we can do sorting using the built-in Sort / OrderBy methods with the Comparison delegate, the IComparer , and IComparable interfaces.
To sort an array of objects, you use the sort() method and provide a comparison function that determines the order of objects.
Using LINQ:
var sortedList = _allStatInfo.OrderBy(si => si.date).ToList();
Sorting the original list:
_allStatInfo.Sort(new Comparison<StatInfo>((x, y) => DateTime.Compare(x.date, y.date)));
I see you've got the answer anyway, but...
You can avoid some ugliness by just splitting the statement into two halves:
Comparison<StatInfo> comparison = (x, y) => DateTime.Compare(x.date, y.date);
_allStatInfo.Sort(comparison);
You might want to consider just calling CompareTo
directly, too:
Comparison<StatInfo> comparison = (x, y) => x.date.CompareTo(y.date);
_allStatInfo.Sort(comparison);
You could create an IComparer<T>
implementation using my ProjectionComparer
class -
it's part of MiscUtil, and I've included an uncommented version at the bottom of
this answer. You'd then write:
_allStatInfo.Sort(ProjectionComparer<StatInfo>.Create(x => x.date));
Even if you're using .NET 2.0, you can still use LINQ by way of LINQBridge.
Here's the ProjectionComparer
class required for the second answer. The first couple of classes are really just helpers to let generic type inference work better.
public static class ProjectionComparer
{
public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>
(Func<TSource, TKey> projection)
{
return new ProjectionComparer<TSource, TKey>(projection);
}
public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>
(TSource ignored, Func<TSource, TKey> projection)
{
return new ProjectionComparer<TSource, TKey>(projection);
}
}
public static class ProjectionComparer<TSource>
{
public static ProjectionComparer<TSource, TKey> Create<TKey>
(Func<TSource, TKey> projection)
{
return new ProjectionComparer<TSource, TKey>(projection);
}
}
public class ProjectionComparer<TSource, TKey> : IComparer<TSource>
{
readonly Func<TSource, TKey> projection;
readonly IComparer<TKey> comparer;
public ProjectionComparer(Func<TSource, TKey> projection)
: this (projection, null)
{
}
public ProjectionComparer(Func<TSource, TKey> projection,
IComparer<TKey> comparer)
{
projection.ThrowIfNull("projection");
this.comparer = comparer ?? Comparer<TKey>.Default;
this.projection = projection;
}
public int Compare(TSource x, TSource y)
{
// Don't want to project from nullity
if (x==null && y==null)
{
return 0;
}
if (x==null)
{
return -1;
}
if (y==null)
{
return 1;
}
return comparer.Compare(projection(x), projection(y));
}
}
To illustrate Robert C. Cartaino's answer:
public class StatInfo : IComparable<StatInfo>
{
public string contact;
public DateTime date;
public string action;
public int CompareTo(StatInfo value)
{
return this.date.CompareTo(value.date);
}
}
var _allStatInfo = new List<StatInfo>();
// this now sorts by date
_allStatInfo.Sort();
Not the most general solution but good if you're only going to sort by date. And, as Robert said, you can still always override the default sort by passing an IComparer parameter to the sort method.
Use a lambda expression to map a pair to a comparison:
_allStatInfo.Sort((x, y) => x.date - y.date);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With