# Sorting by patients' name or birth

Is there a way to write this simpler?

if(criteria.SortBy =="name")
{
if (criteria.SortDirection == "ascending")
{
physicians.Sort((x, y) => string.Compare(x.Name, y.Name));
}
else
{
physicians.Sort((x, y) => string.Compare(y.Name,x.Name ));

}
}

if (criteria.SortBy == "birth")
{
if (criteria.SortDirection == "ascending")
{
physicians.Sort(new Comparison<Physician>((x, y) => DateTime.Compare(x.DateOfBirth ?? DateTime.MinValue,y.DateOfBirth ?? DateTime.MinValue)));
}
else
{
physicians.Sort(new Comparison<Physician>((x, y) => DateTime.Compare(y.DateOfBirth ?? DateTime.MinValue, x.DateOfBirth ?? DateTime.MinValue)));

}
}


You can use the ComparerExtensions library to help you create comparers more easily.

With it, your code could look something like:

IComparer<Physician> comparer = null;

if (criteria.SortBy == "name")
{
comparer = KeyComparer<Physician>.OrderBy(x => x.Name);
}
else if (criteria.SortBy == "birth")
{
comparer = KeyComparer<Physician>.OrderBy(x => x.DateOfBirth);
}

if (comparer != null)
{
if (criteria.SortDirection != "ascending")
{
comparer = comparer.Reversed();
}

physicians.Sort(comparer);
}


You could use a pattern like this

var factor =
criteria.SortDirection == "ascending" ? 1 : -1;

if(criteria.SortBy =="name")
physicians.Sort((x, y) => string.Compare(x.Name, y.Name) * factor);


UPDATE: Based on CodesInChaos' comment. If the magnitude of the Compare result could be at the extremes, Math.Sign can be used to normalize the result.

var factor =
criteria.SortDirection == "ascending" ? 1 : -1;

if(criteria.SortBy =="name")
physicians.Sort((x, y) => Math.Sign(string.Compare(x.Name, y.Name)) * factor);

• Will work in practice, but not strictly correct. In theory the comparer may return int.MinValue which your code can't negate. Commented Nov 19, 2014 at 13:44
• Good catch by CodesInChaos! In that edge case, the code will fail. Commented Nov 19, 2014 at 16:39