Lớp tập hợp này sẽ duy trì các bản sao và chèn thứ tự sắp xếp cho bản sao. Mẹo là gắn thẻ các mục có giá trị duy nhất khi chúng được chèn vào để duy trì thứ tự sắp xếp ổn định. Sau đó, chúng tôi kết thúc tất cả trong một giao diện ICollection.
public class SuperSortedSet<TValue> : ICollection<TValue>
{
private readonly SortedSet<Indexed<TValue>> _Container;
private int _Index = 0;
private IComparer<TValue> _Comparer;
public SuperSortedSet(IComparer<TValue> comparer)
{
_Comparer = comparer;
var c2 = new System.Linq.Comparer<Indexed<TValue>>((p0, p1) =>
{
var r = _Comparer.Compare(p0.Value, p1.Value);
if (r == 0)
{
if (p0.Index == -1
|| p1.Index == -1)
return 0;
return p0.Index.CompareTo(p1.Index);
}
else return r;
});
_Container = new SortedSet<Indexed<TValue>>(c2);
}
public IEnumerator<TValue> GetEnumerator() { return _Container.Select(p => p.Value).GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public void Add(TValue item) { _Container.Add(Indexed.Create(_Index++, item)); }
public void Clear() { _Container.Clear();}
public bool Contains(TValue item) { return _Container.Contains(Indexed.Create(-1,item)); }
public void CopyTo(TValue[] array, int arrayIndex)
{
foreach (var value in this)
{
if (arrayIndex >= array.Length)
{
throw new ArgumentException("Not enough space in array");
}
array[arrayIndex] = value;
arrayIndex++;
}
}
public bool Remove(TValue item) { return _Container.Remove(Indexed.Create(-1, item)); }
public int Count {
get { return _Container.Count; }
}
public bool IsReadOnly {
get { return false; }
}
}
một lớp học thử nghiệm
[Fact]
public void ShouldWorkWithSuperSortedSet()
{
// Sort points according to X
var set = new SuperSortedSet<Point2D>
(new System.Linq.Comparer<Point2D>((p0, p1) => p0.X.CompareTo(p1.X)));
set.Add(new Point2D(9,10));
set.Add(new Point2D(1,25));
set.Add(new Point2D(11,-10));
set.Add(new Point2D(2,99));
set.Add(new Point2D(5,55));
set.Add(new Point2D(5,23));
set.Add(new Point2D(11,11));
set.Add(new Point2D(21,12));
set.Add(new Point2D(-1,76));
set.Add(new Point2D(16,21));
var xs = set.Select(p=>p.X).ToList();
xs.Should().BeInAscendingOrder();
xs.Count.Should()
.Be(10);
xs.ShouldBeEquivalentTo(new[]{-1,1,2,5,5,9,11,11,16,21});
set.Remove(new Point2D(5,55));
xs = set.Select(p=>p.X).ToList();
xs.Count.Should()
.Be(9);
xs.ShouldBeEquivalentTo(new[]{-1,1,2,5,9,11,11,16,21});
set.Remove(new Point2D(5,23));
xs = set.Select(p=>p.X).ToList();
xs.Count.Should()
.Be(8);
xs.ShouldBeEquivalentTo(new[]{-1,1,2,9,11,11,16,21});
set.Contains(new Point2D(11, 11))
.Should()
.BeTrue();
set.Contains(new Point2D(-1, 76))
.Should().BeTrue();
// Note that the custom compartor function ignores the Y value
set.Contains(new Point2D(-1, 66))
.Should().BeTrue();
set.Contains(new Point2D(27, 66))
.Should().BeFalse();
}
Cấu trúc gắn thẻ
public struct Indexed<T>
{
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<T> Create<T>(int indexed, T value)
{
return new Indexed<T>(indexed, value);
}
}
Trình trợ giúp lambda so sánh
public class Comparer<T> : IComparer<T>
{
private readonly Func<T, T, int> _comparer;
public Comparer(Func<T, T, int> comparer)
{
if (comparer == null)
throw new ArgumentNullException("comparer");
_comparer = comparer;
}
public int Compare(T x, T y)
{
return _comparer(x, y);
}
}