Rounding a value to only a list of certain values in C#
Here's a method using LINQ:
var list = new[] { 12, 15, 23, 94, 35, 48 };
var input = 17;
var diffList = from number in list
select new {
number,
difference = Math.Abs(number - input)
};
var result = (from diffItem in diffList
orderby diffItem.difference
select diffItem).First().number;
EDIT: Renamed some of the variables so the code is less confusing...
EDIT:
The list
variable is an implicitly declare array of int
. The first LINQ statement diffList
defines an anonymous type that has your original number from the list (number
) as well as the difference between it and your current value (input
).
The second LINQ statement result
orders that anonymous type collection by the difference, which is your "rounding" requirement. It takes the first item in that list as it will have the smallest difference, and then selects only the original .number
from the anonymous type.
Assuming the array is sorted, you could perform a binary search in the array, narrowing it down to which two numbers the given number lies between.
Then once you have these two numbers, you simply round to the nearest of the two.
static int RoundToArray(int value, int[] array) {
int min = 0;
if (array[min] >= value) return array[min];
int max = array.Length - 1;
if (array[max] <= value) return array[max];
while (max - min > 1) {
int mid = (max + min) / 2;
if (array[mid] == value) {
return array[mid];
} else if (array[mid] < value) {
min = mid;
} else {
max = mid;
}
}
if (array[max] - value <= value - array[min]) {
return array[max];
} else {
return array[min];
}
}
Using linq:
int value = 17;
var values = new float[] { 12, 15, 23, 94, 35, 48 };
if(value < values.First()) return value.First();
if(value > values.Last()) return value.Last();
float below = values.Where(v => v <= value).Max();
float above = values.Where(v => v >= value).Min();
if(value - below < above - value)
return below;
else
return above;
As long as then number of possible values is quite small this should work. If you have thousands of possible values another solution should be used, which takes advantage of values
being sorted (if it really is sorted).