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