Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A SortedList.IndexOfKey(key) that returns the index of the item where item.key >= key

SortedList<TKey, TValue>.IndexOfKey(key) returns -1 if key is not in the list.

Does this mean I have to implement a binary search myself if I want to find the index of the key in the list that is greater or equal to key? Or is there something out of the box that I overlooked?

I want to get the result in O(log(n)) of course, so please no LINQ iterate and filter magic.

(In general, I'd like to have something like Java's NavigableMap functionality, i.e. features like efficient iteration over a sorted map/dictionary, but for now, an answer to the above question would suffice, I can "extension-method" my way from there somehow)

like image 364
Evgeniy Berezovsky Avatar asked Jan 27 '12 07:01

Evgeniy Berezovsky


People also ask

How does SortedList work in C#?

In C#, SortedList is a collection of key/value pairs which are sorted according to keys. By default, this collection sort the key/value pairs in ascending order. It is of both generic and non-generic type of collection. The generic SortedList is defined in System.

What is SortedList?

A SortedList object internally maintains two arrays to store the elements of the list; that is, one array for the keys and another array for the associated values. Each element is a key/value pair that can be accessed as a DictionaryEntry object. A key cannot be null , but a value can be.

Which collection type represents a collection of key and value pairs that are sorted by keys and are accessible by keys and values?

A SortedList represents a collection of objects stored as key-value pairs that are sorted by the keys.

When should you use a SortedDictionary T class rather than a SortedList T class?

SortedDictionary is implemented with Binary Search Tree, while SortedList is implemented with two internal arrays for keys and values, respectively. SortedList is more memory-efficient than SortedDictionary, and SortedList is faster than SortedDictionary when it needs to go through all items at once.


1 Answers

So here it is, for posterity, including myself, as I'm yet again in need of a NavigableMap in .net. BinarySearch extension methods that work for SortedList<TKey, TValue> and overloads that work for any IList<T>.

public static class BinarySearch4All
{
    public static int BinarySearch<TKey, TValue>(this SortedList<TKey, TValue> sortedList,
            TKey value, IComparer<TKey> comparer = null)
    {
        return BinarySearch(sortedList, 0, sortedList.Count, value, comparer);
    }

    public static int BinarySearch<TKey, TValue>(this SortedList<TKey, TValue> sortedList,
            int index, int length, TKey value, IComparer<TKey> comparer = null)
    {
        return BinarySearch(sortedList.Keys, index, length, value, comparer);
    }

    public static int BinarySearch<T>(this IList<T> list, T value, IComparer<T> comparer = null)
    {
        return BinarySearch(list, 0, list.Count, value, comparer);
    }

    // algorithm courtesy of http://referencesource.microsoft.com/#mscorlib/system/collections/generic/arraysorthelper.cs#114ea99d8baee1be
    public static int BinarySearch<T>(this IList<T> list, int index, int length,
            T value, IComparer<T> comparer = null)
    {
        if (comparer == null)
            comparer = Comparer<T>.Default;
        int lo = index;
        int hi = index + length - 1;
        while (lo <= hi)
        {
            int i = lo + ((hi - lo) >> 1);
            int order = comparer.Compare(list[i], value);

            if (order == 0) return i;
            if (order < 0)
                lo = i + 1;
            else
                hi = i - 1;
        }
        return ~lo;
    }
}

N.B. I wonder why there is no IRandomAccess<T> in .net, which at least IList<T> and arrays would derive from.

SortedList<TKey, TValue> could actually derive from IRandomAccess<TKey>, as well as IRandomAccess<TValue> and IRandomAccess<KeyValuePair<TKey, TValue>>.

like image 81
Evgeniy Berezovsky Avatar answered Sep 25 '22 23:09

Evgeniy Berezovsky