Reputation: 147
I have a list of numbers and if the number that I am looking for is not in the list I want to be able to find the next value that is in the list above and below the number that I have asked for.
double index = 5;
List<double> list = new List<double>() { 1, 2, 3, 7, 8, 9, };
//do code to find next highest/lowest
double higher = 7;
double lower = 3;
for example, because 5 is not exactly in the list itself I want it to return the next item that is closest to 5 both above and below. so for this case, 3 and 7.
Upvotes: 2
Views: 4049
Reputation: 10818
You can use List's Sort()
method, then use LINQ FirstOrDefault()
and LastOrDefault()
List<double> numbers = new List<double>()
{
1, 2, 3, 7, 8, 9
};
double input = 5;
numbers.Sort();
double nextHighest = numbers.FirstOrDefault(x => x > input);
double nextLowest = numbers.LastOrDefault(x => x < input);
Originally I suggested this as a more efficient solution, but this will not work for the number before a given input. It only works for finding a number after the given input.
You can be more efficient since you are using List<T>
, there is a Find()
method that accepts a predicate:
List<double> numbers = new List<double>()
{
1, 2, 3, 7, 8, 9
};
double input = 5;
numbers.Sort();
double nextHighest = numbers.Find(x => x > input);
This will exit the loop immediately upon finding a match (whereas LastOrDefault()
has to iterate the entire collection)
Fiddle for both here
Upvotes: 7
Reputation: 21
The other answer given is not very good if you are going to be using a large list of values, because it needs to index the list twice.
If you make your own loop like this:
double higher = Double::MaxValue;
double lower = Double::MinValue;
double index = 5; // the value you want to get.
List<double> list = {1,2,3,7,8,9}; // the list you're searching.
for(int i = 0; i < list.Count; i++)
{
if(list[i] > index && list[i] < higher)
higher = list[i]; // sets the higher value.
else if(list[i] < index && list[i] > lower)
lower = list[i]; // sets the lower value.
}
After execution, this would give you 3 and 7, the correct values.
I should note that this takes O(n) time, because it only loops once. This will be faster than anything posted at the time of this edit (plus it's pretty easy to see what its doing).
Upvotes: 0
Reputation: 128
You can archieve that by this way. These codes below was tested from my side.
double index = 5;
double higher = 0 ;
double lower = 0;
List<double> list = new List<double>() { 1, 2, 3, 7, 8, 9, };
list.Sort();//Sort list from low to high numbers
if(!list.Contains(index))
{
foreach (var item in list)
{
if(item < index)
{
lower = item;
}
if (item > index)
{
higher = item;
break;
}
}
}
Console.WriteLine(index);//5
Console.WriteLine(lower);//3
Console.WriteLine(higher);//7
Upvotes: -1
Reputation: 1703
In case you want all the occurency
double index = 5;
List<double> list = new List<double>() { 1, 2, 3, 7, 8, 9, };
for(int i =1 ; i <= 9-5 ; i++)
{
List<double> NextHigh = list.Where(x=> x-i == index).ToList();
if(! (NextHigh.Count == 0))
{
NextHigh.Dump();
break;
}
}
for(int i =1 ; i <= 5-1 ; i++)
{
List<double> NextLow = list.Where(x=> x+i == index).ToList();
if( !(NextLow.Count== 0))
{
NextLow.Dump();
break;
}
}
Upvotes: 0
Reputation: 9285
LinQ-Solution:
double index = 5;
List<double> list = new List<double>() { 1, 2, 3, 7, 8, 9, };
double higher=list.OrderBy(q=>q).First(q=>q>index); // 7
double lower=list.OrderByDescending(q=>q).First(q=>q<index); // 3
Explanation: First you sort the list Ascending or Descending. After that all you have to do is to find the greater or smaller number;
You might want to replace First()
by FirstOrDefault()
if you do not want an exception if no higher/lower value exists.
Upvotes: 0
Reputation: 4045
One solution would be sort the list and then iterate over it to find the spot where list[i] < index < list[i+1]. This would take O(n * log(n))
time.
A better solution is simply iterate over the list and use 2 variables that you will update accordingly (let's say max
and min
).
max
will store the maximum value that is below the index.
min
will store the minimum value that is above the index.
That last solution takes O(n)
time.
Upvotes: 0