Here's a fairly simple way to keep a list sorted as you insert. It doesn't keep things sorted if their values change though.
My type is this:
public class Entity
{
public int Quantity;
public string Name;
}
Now, let's write a comparer:
public class EntityComparer : IComparer<Entity>
{
public int Compare(Entity x, Entity y) =>
x.Quantity.CompareTo(y.Quantity) == 0
? x.Name.CompareTo(y.Name)
: x.Quantity.CompareTo(y.Quantity);
}
Then it's a case of inheriting from List<Entity>
and adding our Add
method:
public class EntityList : List<Entity>
{
public void Add(Entity entity, IComparer<Entity> comparer)
{
if (this.IsEmpty())
{
this.Add(entity);
}
else
{
var index = this.BinarySearch(entity, comparer);
this.Insert(index < 0 ? ~index : index, entity);
}
}
}
Now, if I run this code:
var el = new EntityList();
var ec = new EntityComparer();
el.Add(new Entity() { Quantity = 3, Name = "Bob" }, ec);
el.Add(new Entity() { Quantity = 2, Name = "Bob" }, ec);
el.Add(new Entity() { Quantity = 2, Name = "Ally" }, ec);
el.Add(new Entity() { Quantity = 4, Name = "Sally" }, ec);
el.Add(new Entity() { Quantity = 2, Name = "Bob" }, ec);
el.Add(new Entity() { Quantity = 1, Name = "Rob" }, ec);
el.Add(new Entity() { Quantity = 9, Name = "Rob" }, ec);
el.Add(new Entity() { Quantity = 4, Name = "Greg" }, ec);
el.Add(new Entity() { Quantity = 4, Name = "Rob" }, ec);
el.Add(new Entity() { Quantity = 2, Name = "Charlie" }, ec);
I get this result:

Of course you could bake in the comparer as a private nested class within the list if you wanted to hide the implementation away.