views:

190

answers:

5

How to get an Enumerator to an item in a -Sorted- dictionary using key?

Note:GetEnumerator() gets an Enumerator to first element..

But I need to get an Enumerator to the element with a given key in order to gain access to next elements using MoveNext() for example...

Edit: Or a way to access next elements...

Edit: I prefer a const time method...

Thanks

+3  A: 
var enumerator = dictionary.Keys.SkipWhile(k => k != myKey)

Where myKey is the key you're looking for. And you can use the OrderBy extension method if you want to have the keys sorted.

Edit: You can't do it in constant with Dictionary/SortedDictionary. Why not implement your own binary search tree (like SortedDictionary is) and you will have O(log n) time lookup and O(1) time .next()?

Janus Tøndering
+1  A: 

You can't do that with Dictionary. You can accomplish that having possibility of accessing by index, so you can use SortedList instead of Dictionary. Also you can have a look at SkipWhile.

Although you can have some workaround like this :

Dictionary<int, int> dictionary = new Dictionary<int, int>();
foreach (KeyValuePair<int, int> pair in dictionary)
{ 
   // you can check the key you need and assume that the next one will be what you need.
}

But of course this is not the best idea.

Incognito
A: 
var query = yourDictionary.SkipWhile(kvp => kvp.Key != keyToFind);
foreach (var result in query)
{
    // ...
}
LukeH
+1  A: 

If you have Framework >=3.5 installed use SkipWhile Janus Tondering and LukeH suggested. For lower framework versions you have to do it for yourself(f.e. fill a second dictionary with the keyvaluepairs from your key to the end).

Tim Schmelter
A: 

The easiest option is to use a SortedList and then add an extension method to it that returns an IEnumerable whose elements are greater than or equal to the given key. The complexity of the GetElementsGreaterThanOrEqual method below is O(log(n)) to get the first element and then each iteration after that is O(1).

public static class SortedListExtension
{
    public static IEnumerable<KeyValuePair<TKey, TValue>> GetElementsGreaterThanOrEqual<TKey, TValue>(this SortedList<TKey, TValue> instance, TKey target) where TKey : IComparable<TKey>
    {
        int index = instance.BinarySearch(target);
        if (index < 0)
        {
            index = ~index;
        }
        for (int i = index; i < instance.Count; i++)
        {
            yield return new KeyValuePair<TKey, TValue>(instance.Keys[i], instance.Values[i]);
        }
    }

    public static int BinarySearch<TKey, TValue>(this SortedList<TKey, TValue> instance, TKey target) where TKey : IComparable<TKey>
    {
        int lo = 0;
        int hi = instance.Count - 1;
        while (lo <= hi)
        {
            int index = lo + ((hi - lo) >> 1);
            int compare = instance.Keys[index].CompareTo(target);
            if (compare == 0)
            {
                return index;
            }
            else
            {
                if (compare < 0)
                {
                    lo = index + 1;
                }
                else
                {
                    hi = index - 1;
                }
            }
        }
        return ~lo;
    }
}
Brian Gideon