2011-11-08 320 views
2

我有一個方法,應該檢查集合中是否只有一個元素對某些謂詞(作爲Func給出)爲真。LINQ c#集合中的唯一元素

public bool ExistsUnique(Func<T, bool> p) 
    { 
     var tempCol = from i in MyCollection where p(i) select i; 
     return (tempCol.Count() == 1); 
    } 

與此問題是,當其也適用於謂詞 真正的第二元件被發現(例如,集合中存在兩個相同的字符串的)計數仍爲1這意味着它要麼覆蓋第一個元素或從不添加第二個元素,因爲它已經存在。

任何想法如何我可以修復這種方法? thx /Peter

+0

我懷疑[這個問題](http://stackoverflow.com/questions/2740109/can-someone-please-explain-this-lazy-evaluation-code)及其答案可能會幫助你。 – ssamuel

回答

1

必須有一些其他問題。我會懷疑你的謂詞。例如,如預期的那樣,返回2的計數:

 List<string> MyCollection = new List<string>() 
     { 
      "hello", 
      "hello" 
     }; 
     var tempCol = from i in MyCollection where i == "hello" select i; 
     int count = tempCol.Count(); 

我懷疑它是您調用它的方式。以下作品(返回false):

static List<string> MyCollection = new List<string>() 
     { 
      "hello", 
      "hello" 
     }; 

    static bool ExistsUnique(Func<string, bool> p) 
    { 
     var tempCol = from i in MyCollection where p(i) select i; 
     return tempCol.Count() == 1; 
    } 

    static void DoIt() 
    { 
     bool isUnique = ExistsUnique((s) => s.Equals("hello")); 
     Console.WriteLine(isUnique); 
    } 
+0

我想你可能是對的。儘管謂詞my_set.ExistsUnique(s => s.Equals(「Hello」))我認爲很好。我在我的Exists方法中使用完全相同的方法(只是檢查是否至少有一個元素爲真,這是有效的)。這可能是我寫p(i)的方式嗎? – PNS

+0

@PNS:查看我更新的答案。我認爲問題不在於你打電話的方式。 –

+0

現在我真的很困惑,與你的方法和我自己的方法唯一的區別是你的ExistsUnique方法需要字符串,布爾,而我的需要T,布爾,但它仍然應該工作。對? – PNS

1

您確定tempCol已通過MyCollection完整迴環? 是Count()強制完成循環的方法還是懶惰?

例如tempCol.ToList().Count給出正確的結果嗎?

+0

我試過說p(i)|| !p(i)它在集合中添加了所有元素一次(不重複),只是爲了檢查它是否實際遍歷了它所做的所有元素。 – PNS

2

您可以使用LINQ像這樣提供的Single()方法:

public bool ExistsUnique(Func<T, bool> p) 
{ 
    try 
    { 
     var temp = myCollection.Single(x => p(x)); 
    } 
    catch(Exception e) 
    { 
     // log exception 
     return false; 
    } 

    return true; 
} 

「返回滿足指定條件的順序的唯一元素,如果存在多個這樣的元素,則拋出 異常。「

http://msdn.microsoft.com/en-us/library/bb535118.aspx

編輯

爲了避免拋出一個異常,你也可以使用SingleOrDefault()方法:

public bool ExistsUnique(Func<T, bool> p) 
{ 
    return myCollection.SingleOrDefault(x => p(x)) != null; 
} 
+0

這是一個好主意!我試過了,雖然我仍然得到同樣的問題,並且它返回true,即使我嘗試添加兩個相同的字符串。 – PNS

+0

當不需要時拋出異常很慢,當有簡單的方法來做同樣的事情時,可能要小心這種技術,沒有例外。 –

+0

-1請修復拋出異常 –

0

此實現將使它讓你不不得不實際枚舉整個集合,這樣可以節省一些執行時間。

public bool ExistsUnique(Func<T, bool> p) 
{ 
    return MyCollection.Where(i => p(i)).Take(2).Count() == 1; 
} 

Take(2)限制Count僅列舉的前兩個會議的標準。

相關問題