views:

138

answers:

3

I have a hashtable with n number of records. I need to copy out the records between x and y and iterate through them.

How would I do this?

Example:

HT1.Count = 500;

HT2 = HT1[0] - HT1[100];

--edit--

Just so you are aware, the reasoning for this is I am generating PDF's from .MSG files. The problem arises for the end user that when they get a 12GB PDF it causes issues :P

I need to break the PDF's into messages of 250, and then start a new PDF. So order does not really matter, neither does returning the same records each time, as it will only be done once.

A: 

I suggest you consult a reference on hash tables. Hash tables are generally unordered, so your question is meaningless.

mquander
His question amounts to the SELECT TOP(x) clause from SQL. You are asking for a sampling of the data, not necessarily random or ordered, just sample data.
OK, I amend my remark: you could select N at random. However, the way he phrased the question ("copy out the records between x and y") seemed to imply that he is looking for some particular deterministic subset of his data.
mquander
+2  A: 

My bet would be doing a custom function like this:

public IEnumerable<object> GetRange(Hashtable ht, int min, int max) {
    int i = 0;
    foreach (var key in ht.Keys) {
     i++;
     if (i > max) {
      yield break;
     }
     if (i >= min) {
      yield return ht[key];
     } else continue;
    }
}

However, take into account that the order of the keys is not guaranteed, so this can have an unordered sequence of objects

Jhonny D. Cano -Leftware-
Why implement a custom function on the hashtable? Why not just enumerate through using a foreach on the GetEnumerator, then add n values to the HT2.
no need to use yield or anything fancy for this one.
You can do any of this, but hash tables really are unordered. It may not reliably give you the same N items every time, and if it does, it might not still give you the same ones a year from now.
mquander
That's why I wouldn't bother using yield. It seems like if you are manually creating an enumerator (using yield) you would imply to the calling party that you are controlling the output. But you absolutely cannot. Sure you can pick n values from it, but you can't guarantee they will be the same, and you also can't consider them truly random.
+1  A: 

As others have stated, you cannot iterate over a hashtable in the way you seem to want. If, on the other hand, what you want is the result where the keys are in that range, you can do something like this:

    public IDictionary<int, T> GetRange<T>(
        IDictionary<int, T> source, int min, int max)
    {
        // add error checking for min,max, null, etc...
        int capacity = Math.Max(0, max - min);
        Dictionary<int, T> target = new Dictionary<int, T>(capacity);
        for (int key = min; key < max; key++)
        {
            if (source.ContainsKey(key))
            {
                target.Add(key, source[key]);
            }
        }
        return target;
    }

Note that I am using the generic version (Dictionary) instead of the old Hashtable, but the idea would be the same.

Erich Mirabal