我有一个数字列表,我想获得比通过的数字还要多的下一个>=
数字,但是当我传递的值大于列表中的最大数字时,就会出现问题。例如,当我通过41
并且列表中最大的数字是40时,它将不起作用,因此我希望它返回40。
var numbers = new[] {30, 20, 40};
我希望它像这样工作:
numbers.GetNearest(45) -> 40
numbers.GetNearest(40) -> 40
numbers.GetNearest(31) -> 40
numbers.GetNearest(30) -> 30
numbers.GetNearest(29) -> 30
numbers.GetNearest(1) -> 20
单独使用LINQ可能吗,还是有众所周知的算法?
我现在拥有的是这样的:
numbers.OrderBy(n => n).FirstOrDefault(n => n >= minute)
但是当我传递的值大于40时它不起作用
我不想要最接近的数字,但是比我通过的数字还要下一个>=
,但是对于某些大于列表中最大数字的数字将不起作用,因此我只想返回最后一个。
答案 0 :(得分:5)
用DefaultIfEmpty()
定义特殊情况
var numbers = new[] { 30, 20, 40 };
Array.Sort(numbers);
int result = numbers.Where(n => n >= minute).DefaultIfEmpty(numbers.Last()).First();
答案 1 :(得分:3)
更新
var numbers = new[]{30, 20, 40};
var number = 25;
var closest = numbers.OrderBy(n => n)
.Cast<int?>()
.FirstOrDefault(n => n >= number) ?? numbers.Last();
Console.WriteLine(closest);
注意 :由于default(int)
可能是一种更好的方式,因此Cast仅处理0。 >
输出
30
原始
您可以按差异订购
var closest = numbers.OrderBy(x => Math.Abs((long)x - number))
.First();
答案 2 :(得分:1)
您没有提供有关特定条件的足够详细信息,因此我只能给您以下答案:
var numbers = new[] {30, 20, 40};
var ordered = numbers.Select(x => (int?)x).OrderBy(x => x);
int? value = ordered.FirstOrDefault(x => x >= 41) ?? ordered.LastOrDefault();
答案 3 :(得分:0)
有人用Aggregate
发布了答案,但不能完全按照我希望的方式工作,但删除了它。因此,我想出了使用Aggregate
的自己的解决方案,我认为它应该比首先使用OrderBy
更快。
numbers.Aggregate((x, y) =>
{
var min = Math.Min(x, y);
return number <= min ? min : Math.Max(x, y);
});
我花了一段时间才弄清楚,但它解决了我的问题。如果您发现其中有任何缺陷,请告诉我。