private int? FindClosest(IEnumerable<int> numbers, int x) { return (from number in numbers let difference = Math.Abs(number - x) orderby difference, Math.Abs(number), number descending select (int?) number) .FirstOrDefault(); }
Zero means there was no nearest number. If there are two numbers with the same difference, he will choose the closest to zero. If two numbers are at the same distance from zero, a positive number will be selected.
Edit in response to Eric's comment:
Here is a version that has the same semantics, but uses the Min operator. This requires an implementation of IComparable<> , so we can use Min , keeping the number that goes with each distance. I also made it an extension for ease of use:
public static int? FindClosestTo(this IEnumerable<int> numbers, int targetNumber) { var minimumDistance = numbers .Select(number => new NumberDistance(targetNumber, number)) .Min(); return minimumDistance == null ? (int?) null : minimumDistance.Number; } private class NumberDistance : IComparable<NumberDistance> { internal NumberDistance(int targetNumber, int number) { this.Number = number; this.Distance = Math.Abs(targetNumber - number); } internal int Number { get; private set; } internal int Distance { get; private set; } public int CompareTo(NumberDistance other) { var comparison = this.Distance.CompareTo(other.Distance); if(comparison == 0) {
Bryan watts
source share