2011-11-08 74 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仅列举的前两个会议的标准。