vendredi 17 juillet 2009

Comment trier un objet hashtable sur les valeurs ?

D'accord on est mal parti avec ce titre, car par définition, un objet hashtable n'est pas triable sur les valeurs.

Ce type d'objet est toujours triè sur les clés que l'on insère. À chaque foi que l'on ajoute une entrée, la clé est haché http://fr.wikipedia.org/wiki/Table_de_hachage pour définir sa position dans la table et non pas ajouter l'une derrière l'autre comme dans un tableau ordinaire.

De plus, si on écrit du nouveau code, certainement qu'un objet hashtable n'est pas la bonne manière de faire. Surtout avec les génériques : List<>.

Alors, comment on en arrive là ? En générale, ce cas arrive sur du code existant pour lequel on ne veut pas tout réécrire, à l'origine le besoin était plus simple, question de temps, etc...

Pour les personnes pressées, voici le code de la solution :

using System;
using System.Collections.Generic;
using System.Text;

using System.Collections;

namespace SortHashtable
{
    class Program
    {
        static void Main(string[] args)
        {

            //...
            Hashtable hashtable = new Hashtable();
            hashtable.Add("keyV", 55);
            hashtable.Add("keyG", 99);
            hashtable.Add("keyB", 25);
            hashtable.Add("keyD", 13);
            hashtable.Add("keyL", 77);

            //On affiche les éléments avant le tri.
            System.Console.WriteLine("Avant le tri dans l'objet Hashtable:");
            foreach (DictionaryEntry dicEntry in hashtable)
            {
                System.Console.WriteLine("Key={0} Value={1}", dicEntry.Key, dicEntry.Value);
            }


            IComparer dicEntryComparer = new ComparerDictionnaryEntryOnDoubleValue();

            //On déclare un arraylist.
            ArrayList al = new ArrayList();

            //On ajoute la hashtable dans un arraylist.
            al.AddRange(hashtable);

            //On tri la liste.
            al.Sort(dicEntryComparer);

            //On affiche les éléments de l'arraylist trié.
            System.Console.WriteLine("\nAprès le sort sur les valeurs dans l'objet ArrayList (ordre croissant):");
            foreach (DictionaryEntry dicEntry in al)
            {
                System.Console.WriteLine("Key={0} Value={1}", dicEntry.Key, dicEntry.Value);
            }

            //On fait une pose pour voir le résultat.
            System.Console.ReadKey();

        }
    }

    public class ComparerDictionnaryEntryOnDoubleValue : IComparer
    {
        int IComparer.Compare(object right, object left)
        {
            // Conversion en double des valeurs.
            double l = Convert.ToDouble(((DictionaryEntry)left).Value);
            double r = Convert.ToDouble(((DictionaryEntry)right).Value);

            // On compare l'élément de gauche avec celui de droite.
            // Le boolean qui en résulte informe si l'élément de gauche
            // est plus grand que celui de droite.
            //return (Comparer<double>.Default.Compare(l, r)); // Tri en ordre décroissant.
            return (Comparer<double>.Default.Compare(r, l)); // Tri en ordre croissant.
        }
    }

}
Voici le résutat que vous devez avoir :

Aucun commentaire:

Enregistrer un commentaire

Membres