1

I know this question has been asked before, but the other questions are only about finding the CLOSEST. I dont want that. I need the LOWEST between two values. For example if this is the list: Code from How to get the closest number from a List<int> with LINQ?:

List<int> numbers = new List<int>();
numbers.Add(2);
numbers.Add(5);
numbers.Add(7);
numbers.Add(10)

and the number to find is 9, I want it to return the 7 item, not 10 even though its closer. This code finds the closest, but any time I change it to find the lowest in the range it breaks for other situations where the inputted number is one of the numbers in the list(for example 7 or 10):

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

How do I alter that code to support what I need to do?

I know I could use binarysearch... I don't want to use that, I want to use linq if possible.

Community
  • 1
  • 1
FrostyFire
  • 3,212
  • 3
  • 29
  • 53

3 Answers3

8
var numbers = new List<int> { 2, 5, 7, 10 };
var seven = numbers.Where(n => n <= 9).Max();
danielnixon
  • 4,178
  • 1
  • 27
  • 39
1

even @danielnixon answer is good, this uses agregate

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

if (closerLow > number) closerLow = null;
bto.rdz
  • 6,636
  • 4
  • 35
  • 52
  • Performance perspective as the list becomes larger (1000k or so), the method with Abs and Aggregate tends to be bit slower. You may want to check that if your dataset is larger. – GeekzSG Dec 22 '14 at 04:24
  • are you sure? If it is necesary it should be tested. trying to guess is not good – bto.rdz Dec 22 '14 at 04:31
  • There's a problem with this: what if `number` is 0, or some other value smaller than the smallest element in the list? This solution returns the greatest value in the list - not what is wanted. Other solutions using `Where` etc. at least raise an exception in that scenario. – mhawke Dec 22 '14 at 06:59
  • @bto.rdz - yes that is tested with large data set – GeekzSG Dec 24 '14 at 02:01
1

If you have to consider cases where the list will not any number closest, the code would look like,

    private static int? GetClosest(List<int> numbers, int number)
    {
        var shorterEnumerable = numbers.Where(x => x <= number);
        var shorterArray = shorterEnumerable as int[] ?? shorterEnumerable.ToArray();
        if (shorterArray.Length > 1)
            return shorterArray.Max();

        return null;
    }
GeekzSG
  • 943
  • 1
  • 11
  • 28