# [ACCEPTED]-LINQ to find the closest number that is greater / less than an input-linq

Score: 20

with Linq assuming that the list is ordered 14 I would do it like this:

``````var l = new List<int>() { 3, 5, 8, 11, 12, 13, 14, 21 };
var lessThan11 = l.TakeWhile(p => p < 11).Last();
var greaterThan13 = l.SkipWhile(p => p <= 13).First();
``````

EDIT:

As I have 13 received negative feedback about this answer 12 and for the sake of people that may see 11 this answer and while it's accepted don't 10 go further, I explored the other comments 9 regarding BinarySearch and decided to add 8 the second option in here (with some minor 7 change).

This is the not sufficient way 6 presented somewhere else:

``````var l = new List<int>() { 3, 5, 8, 11, 12, 13, 14, 21 };
var indexLessThan11 = ~l.BinarySearch(10) -1;
var value = l[indexLessThan11];
``````

Now the code above 5 doesn't cope with the fact that the value 4 `10` might actually be in the list (in which 3 case one shouldn't invert the index)! so 2 the good way is to do it:

``````var l = new List<int>() { 3, 5, 8, 11, 12, 13, 14, 21 };
var indexLessThan11 = l.BinarySearch(10);
if (indexLessThan11 < 0) // the value 10 wasn't found
{
indexLessThan11 = ~indexLessThan11;
indexLessThan11 -= 1;
}
var value = l[indexLessThan11];
``````

I simply want to 1 note that:

``````l.BinarySearch(11) == 3
//and
l.BinarySearch(10) == -4;
``````
Score: 11

Use `Array.BinarySearch` - no need for LINQ or visiting on average 5 half the elements to find your target.

There 4 are also a variety of `SortedXXX` classes that may 3 be suitable for what you're doing [that 2 will have such efficient O(log N) searches 1 built-in]

Score: 6

You can do this using a binary search. If 6 your searching for 11, well obviously you'll 5 get the index your after. If you search 4 for 10 and use the bitwise complement of 3 the result, you'll get the closest match.

``````   List<int> list = new List<int>(){3,5,8,11,12,13,14,21};

list.Sort();

int index = list.BinarySearch(10);

int found =  (~index)-1;

Console.WriteLine (list[found]); // Outputs 8
``````

The 2 same goes searching in the other direction

``````int index = list.BinarySearch(15);

Console.WriteLine("Closest match : " + list[+~index]); // Outputs 21
``````

Binary 1 searches are also extremely fast.

Score: 5

closest number below 11:

``````        int someNumber = 11;
List<int> list = new List<int> { 3, 5, 8, 11, 12, 13, 14, 21 };

var intermediate = from i in list
orderby i descending
select i;

var result = intermediate.FirstOrDefault();
``````

closest number above 1 13:

``````        int someNumber = 13;
List<int> list = new List<int> { 3, 5, 8, 11, 12, 13, 14, 21 };

var intermediate = from i in list
orderby i
select i;

var result = intermediate.FirstOrDefault();
``````
Score: 1

``````List<int> myList = new List<int>() { 3, 5, 8, 11, 12, 13, 14, 21 };
int n = 11;
int? smallerNumberCloseToInput = (from n1 in myList
where n1 < n
orderby n1 descending
select n1).First();

int? largerNumberCloseToInput = (from n1 in myList
where n1 > n
orderby n1 ascending
select n1).First();
``````

0

Score: 1
``````var list = new List<int> {14,2,13,11,5,8,21,12,3};
var tested = 11;

var closestGreater = list.OrderBy(n => n)
.FirstOrDefault(n => tested < n); // = 12

var closestLess = list.OrderByDescending(n => n)
.FirstOrDefault(n => tested > n); // = 8

if (closestGreater == 0)
System.Diagnostics.Debug.WriteLine(
string.Format("No number greater then {0} exists in the list", tested));

if (closestLess == 0)
System.Diagnostics.Debug.WriteLine(
string.Format("No number smaler then {0} exists in the list", tested));
``````

0

Score: 1

Here is my way hope this helps somebody!

``````List<float> list = new List<float> { 4.0f, 5.0f, 6.0f, 10.0f, 4.5f,  4.0f, 5.0f, 6.0f, 10.0f, 4.5f, 4.0f, 5.0f, 6.0f, 10.0f };
float num = 4.7f;

float closestAbove = list.Aggregate((x , y) => (x < num ? y : y < num ? x : (Math.Abs(x - num)) < Math.Abs(y - num) ? x : y));
float closestBelow = list.Aggregate((x , y) => (x > num ? y : y > num ? x : (Math.Abs(x - num)) < Math.Abs(y - num) ? x : y));

Console.WriteLine(closestAbove);
Console.WriteLine(closestBelow);

``````

This 2 means you dont have to order the list

Credit: addapted 1 from here: How to get the closest number from a List<int> with LINQ?

The Expanded Code

``````float closestAboveExplained = list.Aggregate((closestAbove , next) => {
if(next < num){
return closestAbove;
}

if(closestAbove < num){
return next;
}

else{
if(Math.Abs(closestAbove - num) < Math.Abs(next - num)){
return closestAbove;
}
}
return next;
});

``````
Score: 0

You can use a query for this such as:

``````List<int> numbers = new List<int>() { 3, 5, 8, 11, 12, 13, 14, 21 };
List<int> output = (from n in numbers
where n > 13 // or whatever
orderby n ascending //or descending
select n).ToList();
``````

0

More Related questions