views:

1776

answers:

5

What is the easiest way to traverse a hashtable's keys in ascending alphabetical order?

+7  A: 

This is fairly dependent upon what the type of the key is. But lets assume for a minute that they are strings. You could use the following LINQ query

Hashtable table = GetHashTable();
var keys = table.Keys.Cast<String>().OrderBy(x => x);

For more complex structures the LINQ query is only slightly different. Lets assume you had the following definition for a key

struct Name {
  public string First;
  public string Last;
  // Equality code omitted
}

The LINQ code would be the following

Hashtable table = GetHashtable();
var keys = table.Keys.Cast<Name>().OrderBy(x => x.First).ThenBy(x => x.Last);
JaredPar
"Cannot resolve symbol Cast" :(
SeasonedCoder
@SeasonedCoder: you need to include System.Linq. See http://msdn.microsoft.com/en-us/library/bb341406.aspx
Brian Rasmussen
+1  A: 

Thats not really what hash tables are designed for (they are made to have uniform distribution of keys). Use a sorted tree?

JH
I have to work with legacy code. For now I feel quite reluctant to refactor it to use something like SortedDictionary, etc. But still I need to traverse the keys (which are strings) in alphabet order.
SeasonedCoder
+2  A: 

If you want a map which keeps its keys in natural order, I suggest you don't use Hashtable to start with. If you're still using 1.1, using System.Collections.SortedList. If you're using 2.0 or higher, use SortedList<TKey, TValue> or SortedDictionary<TKey, TValue>. The latter two are largely the same in terms of API, but have different performance characteristics - see the docs for more information.

Jon Skeet
I like the SortedDictionary idea. Is there an easy way to cast between Hashtable and SortedDictionary<string, string>?
SeasonedCoder
No - they're separate types. You can create a new SortedDictionary from a Hashtable, with a bit of care. But if you're using .NET 2.0 anyway, why are you using Hashtable in the first place? You should be able to just replace Hashtable with SortedDictionary in most cases, unless you really need the O(1) lookup.
Jon Skeet
+2  A: 

Well, I found this snippet to be the most suitable to my situation:

Hashtable settings = GetSettings();
ArrayList keys = new ArrayList();
keys.AddRange(settings.Keys);
keys.Sort();
foreach (object key in keys)
{
    // Logic here
}

SeasonedCoder
A: 

It'll probably be slightly faster to use SortedList -

SortedList settings = new SortedList(GetSettings());
foreach (object key in settings.Keys)
{
    //logic
}

creating & sorting the ArrayList is O(n) + O(nlog n) = O(nlog n), whereas the SortedList constructor (according to the docs) is O(n), so it'll be faster to use SortedList directly rather than using an arraylist and explicitly sorting

thecoop