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

后端 未结 8 637
猫巷女王i
猫巷女王i 2021-02-05 19:57

Suppose I have this number list:

List = new List(){3,5,8,11,12,13,14,21}

Suppose that I want to get the closest number th

相关标签:
8条回答
  • 2021-02-05 20:33

    This is my answer

    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 讨论(0)
  • 2021-02-05 20:33
    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 讨论(0)
  • 2021-02-05 20:37

    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 讨论(0)
  • 2021-02-05 20:38

    You can do this using a binary search. If your searching for 11, well obviously you'll get the index your after. If you search for 10 and use the bitwise complement of 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 same goes searching in the other direction

    int index = list.BinarySearch(15);
    
    Console.WriteLine("Closest match : " + list[+~index]); // Outputs 21
    

    Binary searches are also extremely fast.

    0 讨论(0)
  • 2021-02-05 20:44

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

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

    0 讨论(0)
  • 2021-02-05 20:55

    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 means you dont have to order the list

    Credit: addapted 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;
    });
    
    
    0 讨论(0)
提交回复
热议问题