找到列表中最接近的较高数字和最接近的较低数字的差异

Find the difference to the closest higher number and the closest lower number in a list

我有一个 int 列表,我想从给定的 referenceNumber 中找出最接近的较小数字和最接近的较大数字的差异。 所以在这种情况下,如果 referenceNumber 是 5 。它如何输出 closestLowerNumber = 1 和 closestHigherNumber = 3 ?

List<int> Test = new List<int>() {2, 1, 4, 8 };

        int referenceNumber = 5;
        int closestLowerNumber;
        int closestHigherNumber;

/* closestLowerNumber 是与最接近的小数 (1) 的差值 closestHigherNumber 是与最接近的较高数字 (3) 的差 */

这可能是一种半有效的方法(根据数据,不排序可能更有效):

var test = new List<int>() { 2, 1, 4, 8 };
int referenceNumber = 5;
int closestLowerNumber = 0;
int closestHigherNumber = 0;

foreach (var val in test.OrderBy(v => v))
{
    if (val < referenceNumber)
    {
        closestLowerNumber = val;
    }
    else if (val > referenceNumber)
    {
        closestHigherNumber = val;
        break;
    }
}

Console.WriteLine(string.Format("Closest low: {0}, Closest high: {1}, Distance low: {2}, Distance high: {3}", closestLowerNumber, closestHigherNumber, (referenceNumber - closestLowerNumber), (closestHigherNumber - referenceNumber)));

输出:

Closest low: 4, Closest high: 8, Distance low: 1, Distance high: 3

Try it online

请注意,这假设至少有 1 个数字较小和 1 个数字较大。如果不是这种情况,closestLowerNumberclosestHigherNumber 将保持为 0 并给出奇怪的结果。因此,使用可为空的 int 可能是明智的,这样您就可以使用 closestLowerNumber.HasValue.

检查它是否已设置 (int? closestLowerNumber)

尽管这可以在 LINQ 中完成,但这不是解决此任务的最有效方法。我会选择这样的东西:

int referenceNumber = 5;
int? closestLowerNumber = null;
int? closestHigherNumber = null;

foreach (var i in Test)
{
    if (i < referenceNumber)
    {
        if (!closestLowerNumber.HasValue || closestLowerNumber < i)
        {
            closestLowerNumber = i;
        }
    }
    else if (i > referenceNumber)
    {
        if (!closestHigherNumber.HasValue || closestHigherNumber > i)
        {
            closestHigherNumber = i;
        }
    }
}

Console.WriteLine(
    $"{referenceNumber}:{referenceNumber - closestLowerNumber}:{closestHigherNumber - referenceNumber}");

您可以执行以下操作。

var closestLower = Test.Where(x=>x<referenceNum).Min(x=>referenceNum-x);
var closestHigher = Test.Where(x=>x>referenceNum).Min(x=>x-referenceNum);

另一种选择

var closestLower = referenceNum - Test.Where(x=>x<referenceNum).Max();
var closestHigher = Test.Where(x=>x>referenceNum).Min() - referenceNum;

输出 closestLower:1 closestHigher : 3

基本上是 Kirill 的回答,但更清晰:

var Test = new List<int>() { 2, 1, 4, 8 };
var reference = 5;

var closestLower = int.MinValue;
var closestHigher = int.MaxValue;

foreach (var value in Test) {
    switch (value.CompareTo(reference)) {
        case -1: // value < reference
            closestLower = Math.Max(closestLower, value);
            break;
        case 0: // value == reference
            break;
        case 1: // value > reference
            closestHigher = Math.Min(closestHigher, value);
            break;
    }
}