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
How to Find System.Web.Helpers, System.Web.Webpages, and System.Web.Razor
Streamwriter and Utf-8 Byte Order Marks
C# Inheritance and Default Constructors
Request Windows Vista Uac Elevation If Path Is Protected
File Getting Copied to Syswow64 Instead of System32
How to Get the Actual Monitor Name? as Seen in the Resolution Dialog
Yield Statement Implementation
Serialize a Container of Enums as Strings Using JSON.Net
Is It Ok to Use a String as a Lock Object
Make ASP.NET Wcf Convert Dictionary to JSON, Omitting "Key" & "Value" Tags
Force Browser to Download PDF Document Instead of Opening It
Does Stream.Dispose Always Call Stream.Close (And Stream.Flush)
Does C# Support a Variable Number of Arguments, and How
JSONserializersettings and ASP.NET Core
What Is the JSON.Net Equivalent of Xml's Xpath, Selectnodes, Selectsinglenode
How to Downgrade from Visual Studio 2012 Project to Visual Studio 2008
Is It Appropriate to Extend Control to Provide Consistently Safe Invoke/Begininvoke Functionality