2

I have a process that while running outputs a unique int ID and a double value which may not necessarily be unique). For example:

ID, Value 23, 56000 25, 67000 26, 67000 45, 54000

I have to capture these and rank the IDs by by increasing value (smaller to bigger) and then form a string of the form: id1, id2, id3, etc... So in the case above the output would be: 45;26;25;23

There will never be a large amount of IDs - but lets say 10 per pass.

My approach was to use a hashtable to capture the values. The code for sorting is below:

    /// <summary>
    /// Converts a hashtable (key is the id; value is the amount) to a string of the 
    /// format: x;y;z; where x,y & z are the  id numbers in order of increasing amounts
    /// cf. http://stackoverflow.com/questions/3101626/sort-hashtable-by-possibly-non-unique-values for the sorting routine
    /// </summary>
    /// <param name="ht">Hashtable (key is id; value is the actual amount)</param>
    /// <returns>String of the format: x;y;z; where x,y & z are the id numbers in order of increasing amounts</returns>
    public static string SortAndConvertToString(Hashtable ht)
    {
        if (ht.Count == 1)
            return ht.Keys.OfType<String>().FirstOrDefault() +";";

        //1. Sort the HT by value (smaller to bigger). Preserve key associated with the value                                 
        var result = new List<DictionaryEntry>(ht.Count);
        foreach (DictionaryEntry entry in ht)
        {
            result.Add(entry);
        }
        result.Sort(
            (x, y) =>
            {
                IComparable comparable = x.Value as IComparable;
                if (comparable != null)
                {
                    return comparable.CompareTo(y.Value);
                }
                return 0;
            });

        string str = "";
        foreach (DictionaryEntry entry in result)
        {
            str += ht.Keys.OfType<String>().FirstOrDefault(s => ht[s] == entry.Value) + ";";
        }

        //2. Extract keys to form string of the form: x;y;z;
        return str;
    }

I'm just wondering is this the most efficient ways of doing things or is there a more faster way. Comments/suggestions/code-samples much appreciated. Thanks. J.

Set
  • 47,577
  • 22
  • 132
  • 150

1 Answers1

4

You can do this pretty simply using some LINQ and string utilities:

public static string SortAndConvertToString(Hashtable ht)
{
    var keysOrderedByValue = ht.Cast<DictionaryEntry>()
        .OrderBy(x => x.Value)
        .Select(x => x.Key);

    return string.Join(";", keysOrderedByValue);
}

See this fiddle for a working demo.

I'd suggest you use the generic Dictionary<int, double> rather than Hashtable, however. See this related question.

Community
  • 1
  • 1
Charles Mager
  • 25,735
  • 2
  • 35
  • 45