2011-05-10 28 views
40

如何使用LINQ从List<int>获取最接近的数字?如何使用LINQ从列表<int>获取最接近的数字?

例如:

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

我需要找到在列表中数字9最接近的值在这种情况下,10

我如何能做到这一点的LINQ?

+6

你能否澄清一下你的意思是“接近一个列表”? – NateTheGreat 2011-05-10 16:56:05

+2

什么号码,什么名单,你试过什么? – 2011-05-10 16:56:15

+0

您可以提供的任何类型的代码总是有助于让您的问题得到理解并因此得到答案。 :) – 2011-05-10 16:57:34

回答

94

如果使用LINQ to Objects和名单很长,我会用:

List<int> list = new List<int> { 2, 5, 7, 10 }; 
int number = 9; 

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

此方法是稍微比安东尼Pegram建议的解决方案较为复杂,但它具有的优点是你不不必先排序清单。这意味着您的时间复杂度为O(n),而不是O(n*log(n)),并且内存使用率为O(1)而不是O(n)

+0

谢谢你的回答,所以我不明白这个部分:? x:y,那是什么意思? – ale 2011-05-10 18:15:57

+1

这是条件运算符。请参阅http://msdn.microsoft.com/en-us/library/ty67wk28.aspx。我用它来选择'x'或'y',这取决于哪一个最接近'number'。 – 2011-05-10 18:28:56

+2

+1:聚合使用不够。明智的答案。 – 2011-05-11 06:33:08

30

如果你想使用LINQ来执行这个任务,你可以像下面这样做。

List<int> list = new List<int> { 2, 5, 7, 10 }; 
int number = 9; 

// find closest to number 
int closest = list.OrderBy(item => Math.Abs(number - item)).First(); 
+3

这个解决方案的缺点是它必须先排列列表,如果列表很长,会损害性能。查看我的答案,找到一个解决方案,它返回'O(n)'时间的值。 – 2011-05-10 17:36:00

+0

@Elian,我同意。矿可能更具可读性。如果性能不够好,我会争论一个通用循环来完全避免LINQ,但我有自己的工作要做。 ;) – 2011-05-10 17:48:22

+1

我宁愿使用LINQ代替扩展方法。但是,这仍然是美丽的代码。没有过早的优化,只是简单的干净的代码。 +为此。 – Steven 2011-05-10 18:50:07

2

以上解决方案最多都是O(N)

如果您有一个大的列表并且多次执行此最接近元素的查询,那么首先对列表进行排序(O(NlogN)),然后对每个查询使用List<T>.BinarySearch会更高效。与前述方法的O(kN)相比,k查询的性能是O((k+N)logN)

-3

根据您使用的条件,使用此得分最接近或更高。

List<int> list = new List<int> { 2, 5, 7, 10 }; 
int number = 9; 
var closest = list.Where(numbers => numbers > number).First(); 
Console.WriteLine(closest); 
Console.ReadLine(); 

我希望这有用。

相关问题