簡體   English   中英

LINQ 查找大於/小於輸入的最接近數字

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

假設我有這個號碼列表:

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

假設我想得到最接近的小於 11 的數,它是 8 假設我想得到最接近的大於 13 的數,即 14。

列表中的數字不能重復,並且總是有序的。 我該如何為此編寫 Linq?

Linq 假設列表是有序的,我會這樣做:

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();

編輯:

因為我收到了關於這個答案的負面反饋,為了那些可能會看到這個答案的人,雖然它被接受了,但不要再進一步了,我探索了關於 BinarySearch 的其他評論,並決定在這里添加第二個選項(有一些次要的改變)。

這是在其他地方提出的不夠充分的方式:

var l = new List<int>() { 3, 5, 8, 11, 12, 13, 14, 21 };
var indexLessThan11 = ~l.BinarySearch(10) -1;
var value = l[indexLessThan11];

現在上面的代碼沒有處理值10可能實際上在列表中的事實(在這種情況下不應該反轉索引)! 所以好的方法是這樣做:

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];

我只想指出:

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

使用Array.BinarySearch - 不需要 LINQ 或訪問平均一半的元素來找到你的目標。

還有各種SortedXXX類可能適合您正在做的事情[內置高效的 O(log N) 搜索]

您可以使用二分搜索來做到這一點。 如果您搜索 11,很明顯您會得到索引。 如果您搜索 10 並使用結果的按位補碼,您將獲得最接近的匹配項。

   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

向另一個方向搜索也是如此

int index = list.BinarySearch(15);

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

二進制搜索也非常快。

11 以下最接近的數字:

        int someNumber = 11;
        List<int> list = new List<int> { 3, 5, 8, 11, 12, 13, 14, 21 };

        var intermediate = from i in list
                     where i < someNumber
                     orderby i descending
                     select i;

        var result = intermediate.FirstOrDefault();

13 以上最接近的數字:

        int someNumber = 13;
        List<int> list = new List<int> { 3, 5, 8, 11, 12, 13, 14, 21 };

        var intermediate = from i in list
                     where i > someNumber
                     orderby i
                     select i;

        var result = intermediate.FirstOrDefault();
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));

這是我的方式希望這可以幫助某人!

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);

這意味着您不必對列表進行排序

信用:從這里添加: 如何使用 LINQ 從 List<int> 中獲取最接近的數字?

擴展代碼

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;
});

這是我的回答

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();

您可以為此使用查詢,例如:

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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM