Any <T>의 반대 방법은 무엇입니까?


80

컬렉션에 개체가 포함되어 있지 않은지 Linq로 어떻게 확인할 수 있습니까? IE의 반대입니다 Any<T>.

나는 결과를 반전시킬 수 !있지만 가독성을 위해 더 나은 방법이 있는지 궁금했습니다. 확장 프로그램을 직접 추가해야합니까?


그럼 더 읽기 쉬워요 !? Contains, Exists?
Tigran 2012 년

3
예, 없습니다 None<T>. 나는 종종 예를 들어, 내가 좋아하지 않아 (읽기 쉽도록 같은 사용자 지정 확장을 사용하는 !dictionary.ContainsKey(key)I 구현하므로, 구문 dictionary.NoKey(key)대신.
콘라드 Morawski

2
@Morawski : 동시성이 필요하지 않은 경우에도 ConcurrentDictionary정말 편리한 GetOrAdd방법 이기 때문에를 사용하기 시작했습니다 .
Roger Lipscombe

답변:


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의 라이브러리
토마스 레베

60

하나 이상의 레코드가 특정 기준과 일치하는지 확인하는 것과 반대되는 것은 모든 레코드가 기준과 일치하지 않는지 확인하는 것입니다.

전체 예제를 게시하지 않았지만 다음과 같은 반대의 경우를 원하면 :

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

다음을 사용할 수 있습니다.

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

오늘 Google에서이 문제를 발견했습니다. 귀하의 접근 방식에 동의하지만 저는 일반적으로var isJohnNotFound = !MyRecords.All(x => x.FirstName == "John");
Chris

물론, 나는 어리둥절했다. 이 작업을 수행하면 단일 필드가 확인되지 않습니다. 일반적으로 더 비슷 !MyRecords.All(x => InvalidNames.Any(n => n == x.Name));하므로 잘못된 이름 목록에 대해 모든 항목을 확인하십시오. 일치하는 항목이없는 경우에만 결과가 참이됩니다.
Chris

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

컬렉션에 하나의 개체가 포함되어 있지 않은지 확인하고 싶지만 컬렉션의 모든 개체가 주어진 기준과 일치 하는지 확인하고 싶지 않을 때이 스레드를 찾았습니다 . 나는 다음과 같은 검사를 끝냈다.

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

if (!exists)
{
    continue;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.