Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SortedList indexed by something other than the Key

Tags:

c#

I want an indexed list by ID, ordered by a special attribute inside my class.

SortedList, doesnt do this, because it forces me to sort by the key...

Lets say my class is

class example{
 int Id;
 int Order
}

Is there any structure that is indexed like a dictionary, and ordered by something else?

so that I can access data by ID, but in a foreach the data is ordered by Order

like image 696
RagnaRock Avatar asked Jan 25 '12 14:01

RagnaRock


2 Answers

As far as I know, there is no Dictionary type object that will give you that behavior right out of the box.

If you are only worried about accessing in a specified order in a foreach loop then why not use LINQ?

SortedList<int, example> sortedList = new SortedList<int, example>();
... //populate list

var sortedByOrder = from kp in sortedList
                    orderby kp.Value.Order
                    select kp;

foreach (var kp in sortedByOrder)
{
    ... //access will be ordered by example.Order
}

Yes you will pay a penalty in performance, but if it is not an issue this is, IMHO, the easiest way to get what you want.

like image 193
InBetween Avatar answered Sep 19 '22 18:09

InBetween


AFAIK there is nothing provided as standard that will provide ordering based on values, but still provide O(1) lookup like a dictionary. However writing something that can do this is fairly simple:

public class SortedLookup<TKey, TValue> : IEnumerable<TValue>
{
  private readonly Dictionary<TKey, TValue> _lookup;
  private readonly IComparer<TValue> _comparer;

  public SortedLookup(IComparer<TValue> comparer)
  {
    _lookup = new Dictionary<TKey, TValue>();
    _comparer = comparer;
  }

  public TValue this[TKey key] 
  {
    get { return _lookup[key]; }
    set { _lookup[key] = value; }
  }

  public IEnumerator<TValue> GetEnumerator()
  {
    return _lookup.Values.OrderBy(v => v, _comparer).GetEnumerator();
  }

  IEnumerator IEnumerable.GetEnumerator()
  {
    return GetEnumerator();
  }
}
like image 41
Rich O'Kelly Avatar answered Sep 18 '22 18:09

Rich O'Kelly