Le réseau pour les développeurs > Forums - Accueil > .NET Base Class Library > C# 2.0: Sorting a Hashtable by Values
Poser une questionPoser une question
 

TraitéeC# 2.0: Sorting a Hashtable by Values

  • jeudi 7 juin 2007 20:50_Bullines Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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.



Réponses

  • vendredi 8 juin 2007 22:05OmegaManMVP, ModérateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Traitée
     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()));


  • samedi 9 juin 2007 20:04nobugzMVP, ModérateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Traitée
    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.

Toutes les réponses

  • jeudi 7 juin 2007 22:00Bruno_1 Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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.
  • jeudi 7 juin 2007 23:52Andreas JohanssonModérateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     

    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?

  • vendredi 8 juin 2007 05:34Bruno_1 Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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 ?

  • vendredi 8 juin 2007 22:05OmegaManMVP, ModérateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Traitée
     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()));


  • samedi 9 juin 2007 20:04nobugzMVP, ModérateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Traitée
    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.
  • mercredi 13 juin 2007 20:34OmegaManMVP, ModérateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
     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
  • mercredi 13 juin 2007 21:39Bruno_1 Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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.
  • mercredi 13 juin 2007 23:49nobugzMVP, ModérateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    The Wintellect Power Collections have many OrderedSomething collections.  Something ought to fit your bill.
  • lundi 17 décembre 2007 22:42MeMyselfAndI Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Réponse proposée

    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);

             }

        );