Here is an implementation of BinarySearch
that you can use. In addition to the other arguments that would normally be accepted, it also accepts a selector
which determines the actual object that should be compared for each item, and for the value to find it accepts a value of that type, rather than the type of the array.
public static int BinarySearch<TSource, TKey>(this IList<TSource> collection
, TKey item, Func<TSource, TKey> selector, Comparer<TKey> comparer = null)
{
return BinarySearch(collection, item, selector, comparer, 0, collection.Count);
}
private static int BinarySearch<TSource, TKey>(this IList<TSource> collection
, TKey item, Func<TSource, TKey> selector, Comparer<TKey> comparer
, int startIndex, int endIndex)
{
comparer = comparer ?? Comparer<TKey>.Default;
while (true)
{
if (startIndex == endIndex)
{
return startIndex;
}
int testIndex = startIndex + ((endIndex - startIndex) / 2);
int comparision = comparer.Compare(selector(collection[testIndex]), item);
if (comparision > 0)
{
endIndex = testIndex;
}
else if (comparision == 0)
{
return testIndex;
}
else
{
startIndex = testIndex + 1;
}
}
}
To use it is simple enough:
public class Foo
{
public double Value { get; set; }
}
private static void Main(string[] args)
{
Foo[] array = new Foo[5];
//populate array with values
array.BinarySearch(.25, item => item.Value);
}