How to Get the Closest Number from a List<Int> with Linq

How to get the closest number from a Listint with LINQ?

If you use LINQ to Objects and the list is long, I would use:

List<int> list = new List<int> { 2, 5, 7, 10 };
int number = 9;

int closest = list.Aggregate((x,y) => Math.Abs(x-number) < Math.Abs(y-number) ? x : y);

This method is slightly more complex than the solution that Anthony Pegram suggested, but it has as advantage that you don't have to sort the list first. This means that you have a time complexity of O(n) instead of O(n*log(n)) and a memory usage of O(1) instead of O(n).

Get maximum closest number from int list

You can do this with LINQ:

int input = 1000;
int? result = numbers
.OrderBy(n => n) // get the numbers in ascending order
.SkipWhile(n => n < input) // skip until the remaining set >= input
.Cast<int?>() // cast to nullable int
.FirstOrDefault(); // take the first or default entry (if no items remain, it will be null)

LINQ to find the closest number that is greater / less than an input

with Linq assuming that the list is ordered 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 received negative feedback about this answer and for the sake of people that may see this answer and while it's accepted don't go further, I explored the other comments regarding BinarySearch and decided to add the second option in here (with some minor change).

This is the not sufficient way 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 doesn't cope with the fact that the value 10 might actually be in the list (in which case one shouldn't invert the index)! so 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 note that:

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

Find closest value in a list in C# with linq?

var diffs = blanks.SelectMany((item, index) => item.Select(entry => new
{
ListIndex = index, // Index of the parent dictionary in the list
Key = entry.Key, // Key
Diff = Math.Abs(entry.Key - X) // Diff between key and X
}));

var closestDiff = diffs.Aggregate((agg, item) => (item.Diff < agg.Diff) ? item : agg);

Dictionary<int, int> closestKeyDict = blanks[closestKey.ListIndex];
int closestKey = closestDiff.Key;
int closestKeyValue = closestKeyDict[closestKey];

The SelectMany clause flattens all the dictionaries entries into a collection of { ListIndex, DictionaryKey, Difference } instances.

This flattened collection is then aggregated to retrieve the item with the minimum difference.

To answer your second questsion:

var diffs = blanks.SelectMany((list, listIndex) => list.
SelectMany((array, arrayIndex) => array.
Select((item, itemIndex) => new
{
ListIndex = listIndex,
ArrayIndex = arrayIndex,
ItemIndex = itemIndex,
Diff = Math.Abs(item - X)
})));

var closestDiff = diffs.Aggregate((agg, item) => (item.Diff < agg.Diff) ? item : agg);

Now in closestDiff you'll find the indices of the closes item (List index, array index and array item index)

Find closest value in an array List with linq?

You can do it in a following way (snippet assumes, that list is not empty)

var x = 700;
var result = list.Select((subList, idx) => new { Value = subList[1], Idx = idx })
.Where(elem => elem.Value < x)
.Select(elem => new { Diff = Math.Abs(x - elem.Value), elem.Idx })
.OrderBy(elem => elem.Diff).FirstOrDefault();

if (result != null)
{
return result.Idx;
}

// case - there is no such index

How to get the list index of the nearest number?

If you want the index of the closest number this will do the trick:

int index = list.IndexOf(closest);

How to get the closest number from a ListPrice with LINQ?

This should do it for you:

// Change these as needed
int orderWidth = 1;
int orderHeight = 1;

var bestMatch = (from item in itemorder
where item.width >= orderWidth
where item.height >= orderHeight
orderby item.width * item.height
select item).FirstOrDefault();

This LINQ query filters out all items whose size are less than the ordered size. Then it orders the remaining items in ascending order. Finally, it picks the first item (== smallest item), or null.

EDIT

Here's an updated solution based on the sum of the sides of each item.

int orderWidth = 4;
int orderHeight = 4;

int orderSum = orderWidth + orderHeight;

var bestMatch = (from item in itemorder
where item.width >= orderWidth
where item.height >= orderHeight
let itemSum = item.width + item.height
let difference = Math.Abs(orderSum - itemSum)
orderby difference
select item).FirstOrDefault();

LINQ to Get Closest Value?

Here's a solution that satisfies the second query in linear time:

var pivot = 21f;
var closestBelow = pivot - numbers.Where(n => n <= pivot)
.Min(n => pivot - n);

(Edited from 'above' to 'below' after clarification)

As for the first query, it would be easiest to use MoreLinq's MinBy extension:

var closest = numbers.MinBy(n => Math.Abs(pivot - n));

It's also possible to do it in standard LINQ in linear time, but with 2 passes of the source:

var minDistance = numbers.Min(n => Math.Abs(pivot - n));
var closest = numbers.First(n => Math.Abs(pivot - n) == minDistance);

If efficiency is not an issue, you could sort the sequence and pick the first value in O(n * log n) as others have posted.

Find closest and smaller value in a list in C# with linq?

Change

Diff = Math.Abs(item - X)

to

Diff = X - item

and then

var closestDiffS = diffSecond.Aggregate((agg, item) => (item.Diff > 0 && item.Diff < agg.Diff) ? item : agg);

Or, you need a Where. I think it's supposed to go here:

var diffSecond = lastList.SelectMany((listS, listIndex) => listS.
SelectMany((array, arrayIndex) => array //Not here, 'cause you need the index
.Select((item, itemIndex) => new
{
ListIndex = listIndex,
ArrayIndex = arrayIndex,
ItemIndex = itemIndex,
Diff = X - item
}).Where(item => item.Diff > 0)
));

To get all the lists with the smallest Diff:

var closestDiffS = diffSecond.GroupBy(item => item.Diff).OrderBy(group => group.Key).FirstOrDefault();

Finding the closest integer value, rounded down, from a given array of integers

You can use List<T>.BinarySearch instead of enumerating elements of list in sequence.

List<int> numbers = new List<int>() { 0, 2000, 4000, 8000, 8500, 9101, 10010 };
int myNumber = 9000;

int r=numbers.BinarySearch(myNumber);
int theAnswer=numbers[r>=0?r:~r-1];


Related Topics



Leave a reply



Submit