Skip to content

Instantly share code, notes, and snippets.

@lucasteles
Created August 29, 2024 18:03
Show Gist options
  • Save lucasteles/5a9e7380539b197960ec0cce0b5d5907 to your computer and use it in GitHub Desktop.
Save lucasteles/5a9e7380539b197960ec0cce0b5d5907 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
SortedHashSet<int> values = [];
Console.WriteLine("Start");
values.Add(10);
values.Add(8);
values.Add(3);
values.Add(5);
values.Add(6);
values.Add(0);
values.Add(7);
values.Add(2);
values.Add(1);
foreach (var x in values)
Console.WriteLine(x);
Trace.Assert(values.Contains(2));
Console.WriteLine("Finish!");
[Serializable, DebuggerDisplay("Count = {Count}")]
public sealed class SortedHashSet<T> : IReadOnlySet<T>, ISet<T>
{
readonly SortedSet<T> sorted;
readonly HashSet<T> hash;
public SortedHashSet() => (sorted, hash) = (new(), new());
public SortedHashSet(IReadOnlyCollection<T> collection, IComparer<T>? comparer = null)
{
var equalityComparer = comparer is not null
? EqualityComparer<T>.Create((x, y) => comparer.Compare(x, y) is 0)
: null;
hash = new(collection, equalityComparer);
sorted = new(collection, comparer);
}
public int Count => hash.Count;
bool ICollection<T>.IsReadOnly => false;
void ICollection<T>.Add(T item) => Add(item);
public bool Add(T item) => hash.Add(item) && sorted.Add(item);
public bool Remove(T item) => hash.Remove(item) && sorted.Remove(item);
public bool Contains(T item) => hash.Contains(item);
public bool IsProperSubsetOf(IEnumerable<T> other) => hash.IsProperSubsetOf(other);
public bool IsProperSupersetOf(IEnumerable<T> other) => hash.IsProperSupersetOf(other);
public bool IsSubsetOf(IEnumerable<T> other) => hash.IsSubsetOf(other);
public bool IsSupersetOf(IEnumerable<T> other) => hash.IsSupersetOf(other);
public bool Overlaps(IEnumerable<T> other) => hash.Overlaps(other);
public bool SetEquals(IEnumerable<T> other) => hash.SetEquals(other);
public SortedSet<T>.Enumerator GetEnumerator() => sorted.GetEnumerator();
IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public void Clear()
{
hash.Clear();
sorted.Clear();
}
public void CopyTo(T[] array, int arrayIndex) => sorted.CopyTo(array, arrayIndex);
public void ExceptWith(IEnumerable<T> other)
{
var values = other as IReadOnlyCollection<T> ?? other.ToArray();
hash.ExceptWith(values);
sorted.ExceptWith(values);
}
public void IntersectWith(IEnumerable<T> other)
{
var values = other as IReadOnlyCollection<T> ?? other.ToArray();
hash.IntersectWith(values);
sorted.IntersectWith(values);
}
public void SymmetricExceptWith(IEnumerable<T> other)
{
var values = other as IReadOnlyCollection<T> ?? other.ToArray();
hash.SymmetricExceptWith(values);
sorted.SymmetricExceptWith(values);
}
public void UnionWith(IEnumerable<T> other)
{
var values = other as IReadOnlyCollection<T> ?? other.ToArray();
hash.UnionWith(values);
sorted.UnionWith(values);
}
}
Start
0
1
2
3
5
6
7
8
10
Finish!
{
"version": 1,
"target": "Run",
"mode": "Debug"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment