我有一个方法可以检查集合中是否只有一个元素对某个谓词(给定为Func)保持为真。
public bool ExistsUnique(Func<T, bool> p)
{
var tempCol = from i in MyCollection where p(i) select i;
return (tempCol.Count() == 1);
}
这个问题是当第二个元素对谓词也成立时 找到(例如,集合中存在两个相同的字符串),计数仍为1.这意味着它要么覆盖第一个元素,要么从不添加第二个元素,因为它已经存在。
关于如何修复此方法的任何想法? 谢谢 /彼得
答案 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
仅枚举满足条件的前两个。