LINQ c#集合中的唯一元素

时间:2011-11-08 00:07:15

标签: c# linq collections predicate

我有一个方法可以检查集合中是否只有一个元素对某个谓词(给定为Func)保持为真。

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

这个问题是当第二个元素对谓词也成立时 找到(例如,集合中存在两个相同的字符串),计数仍为1.这意味着它要么覆盖第一个元素,要么从不添加第二个元素,因为它已经存在。

关于如何修复此方法的任何想法? 谢谢 /彼得

4 个答案:

答案 0 :(得分: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;
}
  

&#34;返回满足指定条件的序列的唯一元素,并抛出   如果存在多个此类元素,则为例外。&#34;

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

修改

为避免抛出异常,您还可以使用SingleOrDefault()方法:

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

答案 1 :(得分:1)

您确定tempCol完全通过MyCollection进行了循环吗? Count()是强制完整循环的方法还是懒惰?

例如tempCol.ToList().Count会给出正确的结果吗?

答案 2 :(得分: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);
    }

答案 3 :(得分:0)

这个实现可以让你不必实际枚举整个集合,这样可以节省一些执行时间。

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

Take(2)限制Count仅枚举满足条件的前两个。