patterncsharpMinor
Comparer that compares by int than by enum type
Viewed 0 times
comparesthanenumtypethatcomparerint
Problem
Below is the implementation of a comparer that compares objects of type
I know, it's a trivial piece of code, however I am happy about any comments about the realization. :)
Region first by index and then by it's type. The sort order of the type is defined within the comparer.I know, it's a trivial piece of code, however I am happy about any comments about the realization. :)
public class Region
{
public RegionType Type { get; set; }
public int Index { get; set; }
}
public enum RegionType
{
DeletionBeforeNamedRegion,
DeletionWithinNamedRegion,
DeletionAfterNamedRegion,
InsertionBetweenNamedRegions,
InsertionWithinNamedRegion,
NamedRegion,
}
public class RegionComparer : IComparer
{
private static readonly List sortOrderByType = new List
{
RegionType.DeletionBeforeNamedRegion,
RegionType.NamedRegion,
RegionType.DeletionWithinNamedRegion,
RegionType.InsertionWithinNamedRegion,
RegionType.DeletionAfterNamedRegion,
RegionType.InsertionBetweenNamedRegions,
};
public int Compare(Region x, Region y)
{
if (x == null && y == null)
return 0;
if (x == null) return -1;
if (y == null) return 1;
var result = x.Index.CompareTo(y.Index);
if (result != 0) return result;
var xSort = sortOrderByType.IndexOf(x.Type);
var ySort = sortOrderByType.IndexOf(y.Type);
#if DEBUG
if (xSort < 0 || ySort < 0)
throw new NotImplementedException($"Sort order for region type '{(xSort < 0 ? x.Type : y.Type)}' is not defined. Please extend the '{nameof(sortOrderByType)}' list." );
#else
if (xSort < 0) xSort = int.MaxValue;
if (ySort < 0) ySort = int.MaxValue;
#endif
return xSort.CompareTo(ySort);
}
}Solution
private static readonly List sortOrderByType = new List
{
RegionType.DeletionBeforeNamedRegion,
RegionType.NamedRegion,
RegionType.DeletionWithinNamedRegion,
RegionType.InsertionWithinNamedRegion,
RegionType.DeletionAfterNamedRegion,
RegionType.InsertionBetweenNamedRegions,
};Sorting needs to be fast, right? So how about using a dictionary for the oder lookup and not the O(n)
List.IndexOf?private static readonly Dictionary _regionTypeOrder = new RegionType[]
{
RegionType.DeletionBeforeNamedRegion,
RegionType.NamedRegion,
RegionType.DeletionWithinNamedRegion,
RegionType.InsertionWithinNamedRegion,
RegionType.DeletionAfterNamedRegion,
RegionType.InsertionBetweenNamedRegions,
}
.Select((x, i) => new { Key = x, Order = i })
.ToDictionary(x => x.Key, x => x.Order);with it, the lines
var xSort = sortOrderByType.IndexOf(x.Type);
var ySort = sortOrderByType.IndexOf(y.Type);can become
var xSort = _regionTypeOrder[x.Type];
var ySort = _regionTypeOrder[y.Type];var xSort = sortOrderByType.IndexOf(x.Type);
var ySort = sortOrderByType.IndexOf(y.Type);
if (xSort < 0) xSort = int.MaxValue;
if (ySort < 0) ySort = int.MaxValue;the index should never be less then zero. If it is, then there is an error. Its an enum and the property isn't nullable so I think the protection isn't necessary.
After getting ther
RegionType order from the dictionary you should be able to immediately call thisreturn xSort.CompareTo(ySort);Code Snippets
private static readonly List<RegionType> sortOrderByType = new List<RegionType>
{
RegionType.DeletionBeforeNamedRegion,
RegionType.NamedRegion,
RegionType.DeletionWithinNamedRegion,
RegionType.InsertionWithinNamedRegion,
RegionType.DeletionAfterNamedRegion,
RegionType.InsertionBetweenNamedRegions,
};private static readonly Dictionary<RegionType, int> _regionTypeOrder = new RegionType[]
{
RegionType.DeletionBeforeNamedRegion,
RegionType.NamedRegion,
RegionType.DeletionWithinNamedRegion,
RegionType.InsertionWithinNamedRegion,
RegionType.DeletionAfterNamedRegion,
RegionType.InsertionBetweenNamedRegions,
}
.Select((x, i) => new { Key = x, Order = i })
.ToDictionary(x => x.Key, x => x.Order);var xSort = sortOrderByType.IndexOf(x.Type);
var ySort = sortOrderByType.IndexOf(y.Type);var xSort = _regionTypeOrder[x.Type];
var ySort = _regionTypeOrder[y.Type];var xSort = sortOrderByType.IndexOf(x.Type);
var ySort = sortOrderByType.IndexOf(y.Type);
if (xSort < 0) xSort = int.MaxValue;
if (ySort < 0) ySort = int.MaxValue;Context
StackExchange Code Review Q#151534, answer score: 2
Revisions (0)
No revisions yet.