【问题标题】:Is there an equivalent of "None()" in LINQ?LINQ 中是否有等效的“None()”?
【发布时间】:2013-10-12 19:11:28
【问题描述】:

我遇到过一些情况,我觉得我缺少一种 LINQ 扩展方法,该方法可以有效地检查集合中指定谓词是否不匹配。有AnyAll,但如果我使用以下代码:

if (Objects.All(u => u.Distance <= 0))

如果集合中的所有对象都在 0 码或以下,则返回 true。

if (Objects.Any(u => u.Distance <= 0))

如果集合中至少有一个对象距离我不超过 0 码,则返回 true。

到目前为止一切都很好,这两种方法都很有意义,它们的语法也很有意义。现在,如果我想检查是否没有距离为 0 或更小的对象,我必须将 All 方法中的谓词反转为 >= 0 而不是 <= 0 或调用 !All(),在某些情况下case 会导致代码的可读性很差。

是否没有有效的方法Collection.None(u => u.Distance <= 0) 来检查集合中是否没有 0 码或更少码外的对象?它是语法糖而不是实际问题,但我只是觉得它缺失了。

【问题讨论】:

  • 扩展方法是你的朋友。如果您需要 Collection.None,请定义一个...
  • @DavidArno 已经有一种方法可以有效地完成问题所要求的 (Any)。 OP 不喜欢它,不是因为它不符合 OP 的要求,而是因为它看起来不漂亮。什么好看什么不好看主要是基于意见。我没有投票,也不会投票,但我明白为什么其他人会投票。
  • 我不是在问如何检查集合是否为空,我是在问如果列表中的 none 值与谓词。我并不是说我不喜欢Any,我喜欢Any。我在问 LINQ 中是否存在我觉得缺少的方法:None.
  • 不,它不是重复的,因为“使用 LINQ 检查列表是否为空”涉及检查列表是否为空,而此问题涉及处理没有元素的情况非空列表匹配一些条件。

标签: c# .net linq


【解决方案1】:

None!Any 相同,因此您可以定义自己的扩展方法如下:

public static class EnumerableExtensions
{
    public static bool None<TSource>(this IEnumerable<TSource> source,
                                     Func<TSource, bool> predicate)
    {
        return !source.Any(predicate);
    }
}

【讨论】:

  • None 也与!All 相同,这就是为什么没有None 如此奇怪的原因。我想我会坚持按照您的建议编写自己的扩展程序,并希望他们稍后会添加它。
  • 没有!Any!All 将在一项未通过测试的那一刻成功。 None 表示没有元素通过测试。 !All 可以解释为 AnyNot。在逻辑上,exist neg x 不等于 neg exists x
  • @aevitas None!All 不同,尽管可以创建 NotAll 扩展方法。但为什么不HardlyAnyAFew ;)
  • @aevitas:正如你所说,使用All 你必须反转谓词。有时你需要None;这就是我使用!Any的地方。
  • @dtb None 作为速记可能有用,但不是必需的。 predicate logic 中没有 None 符号。要么是NOT ANY 要么是ALL NOT
【解决方案2】:

你可以自己写Extension Method:

public static bool None(this IEnumerable<T> collection, Func<T, bool> predicate)
{
  return collection.All(p=>predicate(p)==false);
}

或者IQueryable&lt;T&gt;也可以

public static bool None(this IQueryable<T> collection, Expression<Func<TSource, bool>> predicate)
{
  return collection.All(p=> predicate(p)==false);
}

【讨论】:

  • 使用p=&gt;!Predicate(p)更简洁。
  • @KingKing 但可读性较差,虽然这是我个人的想法。
  • @Alireza 当然,这只是你的感觉,我不这么认为。
  • @KingKing 是的。我说的是我个人的感觉,没什么一般的。但有时候 '!'隐藏在字符后面:)
  • == false 可读性较差,因为它不寻常。此外,您不能在第二种情况下执行 predicate(p),尽管您可以返回 !collection.Any(predicate),这在第一个示例中也有好处,即不创建新委托。
【解决方案3】:

更短的版本

static class LinqExtensions
{
    public static bool None<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => !source.Any(predicate);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 2020-09-22
    • 1970-01-01
    相关资源
    最近更新 更多