2011-05-10 60 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(); 

我希望這有用。

相關問題