public void Search(IndexRange[] ranges, int index, IndexRangeSearchApproximation approximation, IndexRangeSearchResult expectedResult) { var searchedIndex = ranges.Search(index, approximation); Assert.Equal(searchedIndex, expectedResult); }
/// <summary> /// Searches an array for the range containing a given index. This method will try to /// find the nearest range in case the given index is not covered within the ranges and /// the value of <paramref name="approximation"/> is not <see cref="IndexRangeSearchApproximation.Exact"/>. /// </summary> /// <param name="ranges">The sorted ranges to search from.</param> /// <param name="index">The index.</param> /// <returns> /// The index of the range if found, otherwise the index of the nearest left or right range depending /// on the value of <paramref name="approximation"/> or -1 if it is <see cref="IndexRangeSearchApproximation.Exact"/>. /// </returns> public static IndexRangeSearchResult Search(this IReadOnlyList <IndexRange> ranges, int index, IndexRangeSearchApproximation approximation = IndexRangeSearchApproximation.Exact) { var startIndex = 0; var endIndex = ranges.Count - 1; var approximationResult = -1; while (startIndex <= endIndex) { var midIndex = (startIndex + endIndex) / 2; var midRange = ranges[midIndex]; if (midRange.Contains(index)) { return(new IndexRangeSearchResult(true, midIndex)); } else if (midRange.FirstIndex < index) { startIndex = midIndex + 1; if (approximation == IndexRangeSearchApproximation.NearestLeft) { approximationResult = midIndex; } } else { endIndex = midIndex - 1; if (approximation == IndexRangeSearchApproximation.NearestRight) { approximationResult = midIndex; } } } return(approximation == IndexRangeSearchApproximation.Exact ? new IndexRangeSearchResult(false, -1) : new IndexRangeSearchResult(false, approximationResult)); }