我有一组具有公共IsVisible
布尔属性的模型对象。我需要做的就是查找至少有一个集合的值是否设置为TRUE
。换句话说,如果我有10,000个对象但第二个是true
,我不需要旋转其他9,998。我已经有了答案。
现在我知道我可以编写自己的迭代函数并在第一个'True
'值处突破,但我希望这是LINQ可以做的事情。实际上,它甚至不需要是LINQ。欢迎任何建议。
更新
请在此处查看我的上一篇文章。我添加了一些测试代码和时间。看起来LINQ与我自己进行测试相比,表现非常糟糕。当然,它更容易编写,但在任务关键时刻,我不再确定。
让我感到惊讶的是,我大部分时间都是运行这些,枚举赢得了一个公平的剪辑,但由于某种原因,当我将测试包装在多个传递中时,它看起来已经切换到使用缓存进行索引算得上最快。
我还注意到,如果我没有将所有内容重置为“false”,那么所有剩余/重复的测试似乎要快得多。不知何故,将所有内容重新设置为FALSE(故意过度杀戮以准确测试......)会改变一切。
有趣。不知道我现在要走哪条路。这个不是一个关键任务系统,所以也许我会追求可读性,但仍然如此。有趣。
答案 0 :(得分:17)
您正在寻找的方法是Enumerable.Any
。
bool anyObjectsVisible = myObjects.Any(myObject => myObject.IsVisible);
这有你正在寻找的确切的短路语义;示例代码类似于:
static bool AreAnyObjectsVisible(IEnumerable<MyObject> myObjects)
{
foreach (var myObject in myObjects)
{
if (myObject.IsVisible) return true;
}
return false;
}
答案 1 :(得分:3)
如果你需要实际找到一个对象,只需使用.First或.FirstOrDefault方法:
var myObject = myCollection.First(x=>x.IsVisible);
或
var myObject = myCollection.FirstOrDefault(x=>x.IsVisible);
它们之间的唯一区别是,如果第二个方法返回默认值(在本例中为null),如果集合中没有这样的对象,则.First方法将抛出异常。
如果您只需要检查是否有任何具有此属性设置的对象,请使用
var thereIsVisibleObject = myCollection.Any(x=>x.IsVisible);
一旦找到相应的对象,所有这些方法都会停止迭代集合。
或者,如果您检查所有对象是否可见/不可见,您可以这样做:
var allTheObjectsAreVisible = myCollection.All(x=>x.IsVisible);
var allTheObjectsAreInvisible = myCollection.All(x=>!x.IsVisible);
但是。所有方法将枚举所有元素(从名称中可以明显看出)。
答案 2 :(得分:0)
这是一个“.Any()”实现:
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource local in source)
{
if (predicate(local))
{
return true;
}
}
return false;
}
所以这就是它,与.Any()没什么“特殊”,它只是“foreach”的包装。没有什么特别值得测试的,微观微观优化方面没有任何责任。