Given a populated SortedList
. I would like to get all the keys (or their index range, what should be a closed int interval (mis
You can solve the problem by running an adapted binary search on the Keys
twice to find the indexes that bound the range of interest in the Keys
collection.
Since IList
does not offer binary search facilities you need to write your own. Fortunately, there is also the option of stealing the ready-made implementation from How to perform a binary search on IList.
Here's an adapted version to find the lower bound:
public static int LowerBound(this IList list, T value, IComparer comparer = null)
{
if (list == null)
throw new ArgumentNullException("list");
comparer = comparer ?? Comparer.Default;
int lower = 0, upper = list.Count - 1;
while (lower <= upper)
{
int middle = lower + (upper - lower) / 2;
int comparisonResult = comparer.Compare(value, list[middle]);
// slightly adapted here
if (comparisonResult <= 0)
upper = middle - 1;
else
lower = middle + 1;
}
return lower;
}
To implement UpperBound
, simply change
if (comparisonResult <= 0)
to
if (comparisonResult < 0)
It's now trivial to do this:
var low = set.Keys.LowerBound(value);
var high = set.Keys.UpperBound(value);
// These extra comparisons are required because the adapted binary search
// does not tell us if it actually found the needle. They could be rolled
// into the methods themselves, but this would require another out parameter.
if (set.Keys[low] != value) ++low;
if (set.Keys[high] != value) --high;
if (low <= high) /* remove keys in the range [low, high] */