Ask a questionAsk a question
 

AnswerC# 2.0: Sorting a Hashtable by Values

  • Thursday, June 07, 2007 8:50 PM_Bullines Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi!

    I have a hashtable in a .NET2.0 project such that:


    Code Snippet

    Hashtable myHT = new Hashtable();
    myHT.Add("Bob",  23);
    myHT.Add("Jane", 14);
    myHT.Add("Dave",  7);
    myHT.Add("Mike", 18);



    I would like to sort myHT by the values, and not the keys.  How would I go about doing that?  I've used IComparer before in .NET 1.1, but it appears to be obsolete in .NET2.0.  Can anybody offer some help?  Thanks in advance.



Answers

  • Friday, June 08, 2007 10:05 PMOmegaManMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
     bruno_1 wrote:
    Dictionary<> is worst than Hashtable for sorting, because they don't even bother themself by putting the IComparer interface for comparing.


    Well yes and no, HashTable had to be the swiss army knife of operations. Dictionary is leaner. A dictionary is only for storing values with a key...there is no need to sort the whole thing...just its keys or values....

    The keys and values can be viewed as List<t>. The List<t> is created from the ICollection returned by the exposed properties on the Dictionary of Keys/Values.

    Here I extract the values, I could have done the keys, and sorted them.

    Code Snippet

    Dictionary<int, string> myDict = new Dictionary<int, string>();
    myDict.Add(2, "This");
    myDict.Add(1, "is");
    myDict.Add(5, "radio");
    myDict.Add(4, "clash");

    List<string> song = new List<string>(myDict.Values);
    song.Sort();

    // This writes out: "clash is radio This"
    Console.WriteLine(string.Join(" ", song.ToArray()));


  • Saturday, June 09, 2007 8:04 PMnobugzMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    System.Collections.Generic.SortedDictionary would be the logical choice.  One of its constructors takes an IComparer<T> as its argument.  Yell if you need sample code.

All Replies

  • Thursday, June 07, 2007 10:00 PMBruno_1 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Just ignore or remove the warning, and implement IComparer, it is the simpler way to do it.I don't think that you can solve directly this with only using a hashtable without the IComparer.
  • Thursday, June 07, 2007 11:52 PMAndreas JohanssonModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    You might want to have a look at Dictionary<T> as it is the hashed table to use in .NET 2.0.

     

    What was your approach to sort after values before?

  • Friday, June 08, 2007 5:34 AMBruno_1 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Dictionary<> is worst than Hashtable for sorting, because they don't even bother themself by putting the IComparer interface for comparing. Could you tell us how you sorted the hashtable by value before ?

  • Friday, June 08, 2007 10:05 PMOmegaManMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
     bruno_1 wrote:
    Dictionary<> is worst than Hashtable for sorting, because they don't even bother themself by putting the IComparer interface for comparing.


    Well yes and no, HashTable had to be the swiss army knife of operations. Dictionary is leaner. A dictionary is only for storing values with a key...there is no need to sort the whole thing...just its keys or values....

    The keys and values can be viewed as List<t>. The List<t> is created from the ICollection returned by the exposed properties on the Dictionary of Keys/Values.

    Here I extract the values, I could have done the keys, and sorted them.

    Code Snippet

    Dictionary<int, string> myDict = new Dictionary<int, string>();
    myDict.Add(2, "This");
    myDict.Add(1, "is");
    myDict.Add(5, "radio");
    myDict.Add(4, "clash");

    List<string> song = new List<string>(myDict.Values);
    song.Sort();

    // This writes out: "clash is radio This"
    Console.WriteLine(string.Join(" ", song.ToArray()));


  • Saturday, June 09, 2007 8:04 PMnobugzMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    System.Collections.Generic.SortedDictionary would be the logical choice.  One of its constructors takes an IComparer<T> as its argument.  Yell if you need sample code.
  • Wednesday, June 13, 2007 8:34 PMOmegaManMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
     Chris Bellini wrote:
    I would like to sort myHT by the values, and not the keys. How would I go about doing that?


     nobugz wrote:
    System.Collections.Generic.SortedDictionary would be the logical choice. One of its constructors takes an IComparer<T> as its argument. Yell if you need sample code.


    Unless I am mistaken Hans, SortedDictionary only sorts on keys and not values:

    "Represents a collection of key/value pairs that are sorted on the key." - SortedDictionary Class MSDN
  • Wednesday, June 13, 2007 9:39 PMBruno_1 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    You're right this is why we asked the poster how he already did it with the hashtable, cause hashtable has similar functionality for the IComparer<T>, and it doesn't provide sorting by value.  And I think it shouldn't because the insertion is done by key(IComparer<T> is on the key). anyway, you can not sort in the same time by key and value.
    However, it is a good idea to mention the SortedDictionary<>, but i think that the solution can not be done just by one collection, there is also the SortedList<Tkey, TValue> wich is less efficient in inserting and removing, but much better for memory consumption than SortedDictionary.
  • Wednesday, June 13, 2007 11:49 PMnobugzMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    The Wintellect Power Collections have many OrderedSomething collections.  Something ought to fit your bill.
  • Monday, December 17, 2007 10:42 PMMeMyselfAndI Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Proposed Answer

    I realize that is thread is 6 months old.  But, since I did not find a newer thread on the topic and I found a solution, I decided to post it.

     

    I had the same problem of needing to have a sorted pair of values.  I had used a hashtable to help build these values fas a summary of a very large collection.  I then needed to get the pairs with highest summary first.  I found the KeyValuePair in the Generics namespace to be very useful.  But to use KeyValuePair, I changed my hashtable to a dictionary.

     

    Dictionary<string, int> dict = new Dictionary<string, int>();

     

    /*  populate dictionary */

     

    List<KeyValuePair<string, int>> summaryList = new List<KeyValuePair<string, int>>();

     

    summaryList.AddRange(dict);

    summaryList.Sort

       (

          delegate(KeyValuePair<string, int> kvp1,

                       KeyValuePair<string, int> kvp2)

             {

                return Comparer<int>.Default.Compare(kvp1.Value, kvp2.Value);

             }

        );

     

    • Proposed As Answer byMeMyselfAndI Tuesday, January 06, 2009 8:37 PM
    •