只需检查集合中至少有一个对象的属性值是否为TRUE

问题描述 投票:7回答:3

我有一组具有公共IsVisible布尔属性的模型对象。我需要做的就是找到至少有一个集合的值设置为TRUE。换句话说,如果我有10,000个物体但第二个是true,我不需要旋转其他9,998。我已经有了答案。

现在我知道我可以编写自己的迭代函数并在第一个'True'值突破,但我希望这是LINQ可以做的事情。实际上,它甚至不需要是LINQ。欢迎任何建议。

顺便说一句,选择的语言是C#。

更新:

在这里看到我的上一篇文章我添加了一些测试代码和时间。看起来LINQ与我自己进行测试相比,表现非常糟糕。当然它写起来更容易,但在关键时刻,我不再确定。

让我感到惊讶的是,大部分时间我都运行了这些,枚举获胜并通过一个公平的剪辑,但由于某种原因,当我在多次传递中包装测试时,它看起来已经切换到带有缓存计数的索引作为最快的。

我还注意到,如果我没有将所有内容重置为“假”,则所有剩余/重复测试似乎要快得多。不知何故,将所有内容重新设置为FALSE(这是故意过度杀戮以准确测试...)会改变一切。

有趣。不知道我现在要走哪条路。这不是一个关键任务系统,所以也许我会追求可读性,但仍然如此。有趣。

c# linq loops testing
3个回答
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;
}

3
投票

如果您需要实际查找对象,只需使用.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);

但是。所有方法都将枚举所有元素(从名称中可以明显看出)。


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”的包装。在微观微观微观优化方面没有什么特别的可以测试,也没有任何责任。

© www.soinside.com 2019 - 2024. All rights reserved.