2013-01-11 74 views
3

我知道你可以在LINQ中使用Any,Exists和Single,但無法完全實現這個功能。我需要做一個基於id的查找來查看它是否在數組中,並確保在該值上只有一個匹配。因爲如果有2它會引起問題..我要檢查的要求是陣列只有一個,每個ID在數組中只有一個。確定數組中是否存在int值

這裏就是我試圖

if(someIntArray.Single(item => item = 3) 
    //... we found the value 8 in the array only once so now we can be confident and do something 
+0

「Single()」不適合你嗎? – svick

+0

回答了我自己的問題。看到答案。 – PositiveGuy

+0

@svick它將如何工作? : - /如果它發現0或2+,它會拋出一個很好的異常。 – 2013-01-11 03:21:32

回答

1

我創建了一個()擴展方法只是這種情況設置:

public static bool One<T>(this IEnumerable<T> sequence) 
{ 
    var enumerator = sequence.GetEnumerator(); 
    return enumerator.MoveNext() && !enumerator.MoveNext(); 
} 

public static bool One<T>(this IEnumerable<T> sequence, Func<T, bool> predicate) 
{ 
    return sequence.Where(predicate).One(); 
} 

//usage 
if (someIntArray.One(item => item == 3)) ... 

Single()的問題在於,如果不是隻有一個元素,它會引發異常。你可以將它封裝在try-catch中,但是在大多數情況下,如果有多個匹配元素,這些都比Count()更清晰,更高效。不幸的是,沒有辦法檢查整個數組來驗證沒有元素或者只有一個匹配謂詞,但是如果有兩個或更多,這至少會「快速失敗」,其中Count()將始終評估整個Enumerable是否有一個匹配元素或五十個。

+0

真棒擴展方法。你能解釋你的代碼嗎?我很想知道你做了什麼,因爲我不熟悉泛型或謂詞。 – PositiveGuy

+0

主要工作是在第一種方法中完成的,該方法使用.NET的IEnumerable和IEnumerator實現,它們幾乎可以在每種集合類型上找到。Enumerable的基本思想是,你從一開始就開始,並通過集合一次推進一個元素,直到你到達最後。在這裏,我們只關心Enumerable只有一個元素;這意味着我們應該能夠前進到Enumerable的第一個元素(第一次調用MoveNext()),但不應該前進到第二個元素。 – KeithS

+0

第二種方法通過調用無參數One()重載來簡單包裝內置的Where()Linq方法;會發生什麼情況是Where()方法以元素順序遍歷Enumerable,並且當它找到一個元素(如果插入到謂詞方法中作爲「item」)返回布爾值「true」,它將該元素添加到它自己的元素Enumerable結果集。這更復雜一點,因爲函數「懶惰地」評估(在任何給定的時間,它只做了足夠的工作來產生迄今爲止所需的結果),但這是它的要點。 – KeithS

0

使用LINQ表達:

var duplicates = from i in new int[] { 2,3,4,4,5,5 } 
       group i by i into g 
       where g.Count() > 1 
       select g.Key 

結果:

{4,5} 

當然,你可以檢查duplicates.Count() > 0或日誌是一個問題的那些或者你需要做的任何事情。

1

我認爲你正在過分譴責這一點。

var targetNumber = 3; 
var hasExactlyOne = someIntArray.Count(i => i == targetNumber) == 1; 
3

這裏是我會怎麼解決這個問題:

if (someIntArray.Count(item => item == 3) == 1) 
{ 
    //only one '3' found in the array 
    ... 
} 
+0

當你有一個5000個整數都是3的數組時,會發生什麼?這個解決方案將貫穿每一個最後的索引,在對兩個索引進行檢查後,所提問題的答案是顯而易見的。 – KeithS

-2

得到它的工作:

if(someIntArray.Single(item => item = 3) > 0) 

DOH

+2

我想你需要閱讀['Enumerable.Single()'](http://msdn.microsoft.com/en-us/library/bb535118.aspx)應該再做一次。這不會像你期望的那樣工作(忽略那裏的任務)。 –

+0

你是對的,我認爲這是工作,而不是。你不想拋出異常,這是問題。我結束了使用「包含」,而不是..我的工作很好...雖然最終,爲我的需要,我不需要確保只有一個存在後,因爲我能夠檢查更上游...所以是的,我還沒有找到這個優雅的代碼糖。 – PositiveGuy