tags:

views:

199

answers:

2

Hi,

I have a Dictionary<> which I want to sort based on value so I've done this by putting the dictionary into a List<> then using the .Sort method.

I've then added this back into a Dictionary<>. Is it possible to lookup the new index/order by using the Dictionary key??

Dictionary<int, MyObject> toCompare = new Dictionary<int, MyObject>();

toCompare.Add(0, new MyObject());
toCompare.Add(1, new MyObject());
toCompare.Add(2, new MyObject());

Dictionary<int, MyObject> items = new Dictionary<int, MyObject>();
List<KeyValuePair<int, MyObject>> values = new List<KeyValuePair<int, MyObject>>   (toCompare);

// Sort.
values.Sort(new MyComparer());

// Convert back into a dictionary.
foreach(KeyValuePair<int, PropertyAppraisal> item in values)
{
      // Add to collection.
  items.Add(item.Key, item.Value);
}

// THIS IS THE PART I CAN'T DO...
int sortedIndex = items.GetItemIndexByKey(0);
+3  A: 

Keep your data in the Dictionary<TKey,TValue>, but use a List<TKey> to sort the keys, then iterate as such:

IDictionary<int, MyObject> dict = new Dictionary<int, MyObject>();
// ... Populate dict with data.

IList<int> keyList = new List<int>();
keyList.AddRange(dict.Keys);

// Sort keyList based on key's value.
// MyObject must implement IComparable<MyObject>.
keyList.Sort(delegate(int x, int y) {
   return dict[x].CompareTo(dict[y]);
});

foreach (int key in keyList) {
   MyObject value = dict[key];
}

This way, your list is merely a sorted index and does not affect your storage algorithm.

spoulson
Do you have a more involved example as I need to sort by value not by key. Also, I'm on .net 2.0.
paulio
Added sort to code snippet.
spoulson
Thanks for your answer.
paulio
I'm still unsure how to lookup the index from keyList after the sort using my key? I'm trying to avoid linear searches through the sorted key list.
paulio
The simplest approach to go from key to sorted index lookup, you'll need to pregenerate a `Dictionary<>` where its key is the key in question, and its value is the index in the sorted list. `int idx = indexLookup[key]`. This is ideal for large sets of data, where a linear search would not scale. But it would not be ideal if the data changes frequently, requiring regeneration of the lookup dictionary.
spoulson
A: 

Take this extension method:

public static Dictionary<TKey, TValue> Sort<TKey, TValue, TSortingKey>(this Dictionary<TKey, TValue> source, 
    Func<KeyValuePair<TKey, TValue>, TSortingKey> selector)
{
    var result = new Dictionary<TKey, TValue>();
    foreach (var pair in source.OrderBy(selector))
        result.Add(pair.Key, pair.Value);
    return result;
}

And usage:

    Dictionary<int, MyType> source = new Dictionary<int, MyType>();
    Dictionary<int, MyType> sortedDictionary = source.Sort(i => i.Value.Property1); //sort dictionary by values (by property "Property1" of type MyType

Hope this helps

Nagg
unfortunately I'm stuck with .net 2.0
paulio