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.