I am writing a program to set a sequence in which various objects will appear in report. The sequence is the Y position (cell) on Excel spreadsheet.
A demo part of co
The trick is to augment your object with a unique key. See the following test which passes. I want to keep my points sorted by their X value. Just using a naked Point2D in my comparison function will cause points with the same X value to be eliminated. So I wrap the Point2D in a tagging class called Indexed.
[Fact]
public void ShouldBeAbleToUseCustomComparatorWithSortedSet()
{
// Create comparer that compares on X value but when X
// X values are uses the index
var comparer = new
System.Linq.Comparer>(( p0, p1 ) =>
{
var r = p0.Value.X.CompareTo(p1.Value.X);
return r == 0 ? p0.Index.CompareTo(p1.Index) : r;
});
// Sort points according to X
var set = new SortedSet>(comparer);
int i=0;
// Create a helper function to wrap each point in a unique index
Action index = p =>
{
var ip = Indexed.Create(i++, p);
set.Add(ip);
};
index(new Point2D(9,10));
index(new Point2D(1,25));
index(new Point2D(11,-10));
index(new Point2D(2,99));
index(new Point2D(5,55));
index(new Point2D(5,23));
index(new Point2D(11,11));
index(new Point2D(21,12));
index(new Point2D(-1,76));
index(new Point2D(16,21));
set.Count.Should()
.Be(10);
var xs = set.Select(p=>p.Value.X).ToList();
xs.Should()
.BeInAscendingOrder();
xs.ShouldBeEquivalentTo(new[]{-1,1,2,5,5,9,11,11,16,21});
}
Utilities to make this work are
A comparer that takes a lambda
public class Comparer : IComparer
{
private readonly Func _comparer;
public Comparer(Func comparer)
{
if (comparer == null)
throw new ArgumentNullException("comparer");
_comparer = comparer;
}
public int Compare(T x, T y)
{
return _comparer(x, y);
}
}
A tagging struct
public struct Indexed
{
public int Index { get; private set; }
public T Value { get; private set; }
public Indexed(int index, T value) : this()
{
Index = index;
Value = value;
}
public override string ToString()
{
return "(Indexed: " + Index + ", " + Value.ToString () + " )";
}
}
public class Indexed
{
public static Indexed Create(int indexed, T value)
{
return new Indexed(indexed, value);
}
}