Any <T>の反対の方法は何ですか


80

コレクションにオブジェクトが含まれていないかどうかをLinqで確認するにはどうすればよいですか。IEの反対Any<T>

結果を反転することはできます!が、読みやすくするために、これを行うためのより良い方法があるかどうか疑問に思いました。自分で拡張子を追加する必要がありますか?


それならもっと読みやすい!ContainsExists
Tigran 2012年

3
ええ、ありませんNone<T>。私は、多くの場合、例えば、私は好きではない(読みやすくするために、このようなカスタム拡張を使用し!dictionary.ContainsKey(key)、私が実装して、構文dictionary.NoKey(key)の代わりに。
コンラートMorawski

2
@Morawski:並行性が必要ない場合でもConcurrentDictionary、非常に便利なGetOrAdd方法であるため、使用を開始しました。
Roger Lipscombe 2012年

回答:


87

None拡張メソッドは簡単に作成できます。

public static bool None<TSource>(this IEnumerable<TSource> source)
{
    return !source.Any();
}

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

1
これは標準のLinqへの素晴らしい追加になると思います。
Ivan

3
@ Ivan、Linq自体にはありませんが、Linq.Extrasライブラリの一部です
Thomas Levesque

60

いずれかの(少なくとも1つの)レコードが特定の基準に一致することを確認するのとは逆に、すべてのレコードが基準に一致しないことを確認します。

あなたは完全な例を投稿しませんでしたが、次のようなものの反対が必要な場合:

var isJohnFound = MyRecords.Any(x => x.FirstName == "John");

あなたが使用することができます:

var isJohnNotFound = MyRecords.All(x => x.FirstName != "John");

今日グーグルでこれに出くわしました、そして私はあなたのアプローチに同意しますが、私は通常使用しますvar isJohnNotFound = !MyRecords.All(x => x.FirstName == "John");
クリス

もちろん、私は間抜けです。私がこれを行うとき、それはチェックされている単一のフィールドではありません。通常は、次のようなものです。!MyRecords.All(x => InvalidNames.Any(n => n == x.Name));したがって、すべてのエントリを無効な名前のリストと照合します。一致するものがない場合にのみ、結果が真になります。
クリス

2

追加された回答に加えて、Any()メソッドをラップしたくない場合はNone()、次のように実装できます。

public static bool None<TSource>(this IEnumerable<TSource> source) 
{
    if (source == null) { throw new ArgumentNullException(nameof(source)); }

    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        return !enumerator.MoveNext();
    }
}

public static bool None<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null) { throw new ArgumentNullException(nameof(source)); }
    if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); }

    foreach (TSource item in source)
    {
        if (predicate(item))
        {
            return false;
        }
    }

    return true;
}

パラメータなしのオーバーロードの場合に加えて、ICollection<T>最適化を適用できます。これは、実際にはLINQの実装には存在しません。

ICollection<TSource> collection = source as ICollection<TSource>;
if (collection != null) { return collection.Count == 0; }

2

コレクションに1つのオブジェクトが含まれていないかどうかを確認したいが、コレクション内のすべてのオブジェクトが指定された基準に一致することを確認したくないときに、このスレッドが見つかりました。私はこのようなチェックをすることになりました:

var exists = modifiedCustomers.Any(x => x.Key == item.Key);

if (!exists)
{
    continue;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.