2012-03-12 4 views
11

내 질문의 핵심 부분은 건너 뛰는 것입니다. 약 20 개의 요소가있는 enum 형식을 사용할 계획입니다. 이 세트를 반복하고 싶지만 매번 한 두 번 건너 뛸 필요가 있습니다. 건너 뛸 내용은 미리 알려져 있습니다. 비교 가능한 예제는 알파벳의 모든 문자로 구성된 enum 유형이며, 반복 할 때 모든 모음을 건너 뛰고 싶습니다.일부 값을 무시하면서 enum 유형을 반복하는 방법은 무엇입니까?

우아하고 효율적인 방법으로 반복 코드를 작성하는 방법은 무엇입니까? 모음으로 구성된 별도의 요소 집합을 만들어야합니까? 내가 문제를 생각하고 있기 때문에 보여줄 코드가 없습니다.

답변

27
var query = Enum.GetValues(typeof(MyEnum)) 
    .Cast<MyEnum>() 
    .Except(new MyEnum[] { MyEnum.A, MyEnum.E }); 
foreach (MyEnum item in query) { 
    ... 
} 

당신은 LINQ의 마법을 얻기 위해 캐스팅해야합니다. Except만으로는 작동하지 않습니다.


UPDATE :

나는 다른 생각이있어. FlagsAttribute을 사용하여 열거 형을 정의하고 정규 값을 2의 거듭 제곱으로 정의 할 수 있습니다. 비트 시프트 왼쪽 연산자 <<으로 가장 쉽게 얻을 수 있습니다. C# 7.0부터는 0b_0000_0000_0010_0000과 같은 이진 리터럴을 사용할 수도 있습니다. 그런 다음 기존 값을 결합하여 새로운 값을 형성 할 수 있습니다.

[Flags] 
enum MyEnum 
{ 
    None = 0, 
    A = 1 << 0, 
    B = 1 << 1, 
    C = 1 << 2, 
    D = 1 << 3, 
    E = 1 << 4, 
    ... 
    X = 1 << 23, 
    Y = 1 << 24, 
    Z = 1 << 25, 
    Vowels = A | E | I | O | U 
} 

지금, 당신은 당신이 하나의 비트 AND-작업과 테스트를 수행 할 수있는, 최초의 솔루션을 통해 장점은이

IEnumerable<MyEnum> query = Enum.GetValues(typeof(MyEnum)) 
    .Cast<MyEnum>() 
    .Where(x => (x & MyEnum.Vowels) == MyEnum.None); 
foreach (MyEnum item in query) { 
    ... 
} 

같은 쿼리를 공식화 할 수 있습니다.

최대 32 개의 지수를 정의 할 수 있습니다. 더 많은 정보가 필요하면 enum의 기본 유형을 long으로 정의하고 최대 64 개의 플래그 값 (기존 플래그 값의 조합)을 사용할 수 있습니다.

[Flags] 
enum MyEnum : long 
{ 
    ... 
} 
+0

아마도 가장 완벽한 답변 일 것입니다. 여기에서하는 가장 쉬운 방법은 생략하려는 열거 형 컬렉션을 지정하는 것입니다. 그런 식으로 건너 뛰기 컬렉션을 저장하고 Except에서 원하는 모든 조건을 전달할 수 있습니다. – SPFiredrake

+0

예, 다양한 쿼리를 보관할 수도 있습니다. –

+1

비트 앤드 만 사용하여 테스트를 만드는 또 다른 솔루션을 추가했습니다. 예외적 인 값을 위해 배열이나 HashSet을 필요로하지 않습니다. 내 업데이트를 참조하십시오. –

1

모음으로 구성된 별도의 요소 집합을 만든 다음 LINQ를 사용하여 두 집합간에 집합의 차이를 가져옵니다. 비아 건너/모든 값을 얻기 위해, 다음 유지하기 위해 어떤 값 표현

int[] vowels = {Letters.A, Letters.E, Letters.I, Letters.O, Letters.U}; 
IEnumerable<int> consonant = Enum.GetValues(typeof(Letters)).Except(vowels); 
foreach (int consonant in consonants) 
{ 
    // Do something with each consonant 
} 
1

나는 아마 LINQ를 사용하십시오 - - Enum.GetValues를 사용 (내가 쓴 형태 보증 된 제네릭 열거/대표 라이브러리 또는 Unconstrained Melody 사용) Where 절.

특정 값을 건너 뛰는 경우 HashSet 또는 이와 비슷한 것이 유용 할 수 있습니다 (물론 하나만 건너 뛰어도 유용 할 수는 없습니다). 조건에 따라 건너 뛰는 경우에는 전체 -blown 술어가 호출됩니다. 예를 들어

는 :

public static IEnumerable<T> AllBut(T skipped) where T : struct 
{ 
    IEqualityComparer<T> comparer = EqualityComparer<T>.Default; 
    return AllBut<T>(t => !comparer.Equals(skipped, t)); 
} 

public static IEnumerable<T> AllBut(Func<T, bool> skipPredicate) where T : struct 
{ 
    IEqualityComparer<T> comparer = EqualityComparer<T>.Default; 
    return Enum.GetValues(typeof(T)) 
       .Cast<T>() 
       .Where(t => skipPredicate(t)); 
} 
관련 문제