2009-12-02 2 views
2

조합을 유도 할 때 자동 생성 숫자를 생성하는 방법은 무엇입니까?C# LINQ 자동 생성 된 숫자 또는 인덱스

public enum Color 
{ 
    Red,Green,Blue 
} 

public enum Vehicle 
{ 
    Car,Bike 
} 

(예) {레드, 자동차}, {레드, 자전거}, {그린, 자동차}, {녹색, 자전거} ...

(존 소총은 저를 도와 해결).

var query = from Color c in Enum.GetValues(typeof(Color)) 
      from Vehicle v in Enum.GetValues(typeof(Vehicle)) 
      select new { Color = c, Vehicle = v }; 

는 지금이

{1,Red,Car},{2,Red,Bike},{3,Green,Car},{4,Green,Bike},{5,Blue,Car},{6,Blue,Bike} 

같은 조합이 자동으로 번호를 생성하는 방법은 무엇입니까 싶어?

답변

5

봅니다 :

int optionNumber = 0; 
var query = from Color c in Enum.GetValues(typeof(Color)) 
      from Vehicle v in Enum.GetValues(typeof(Vehicle)) 
      select new { Number = optionNumber++, Color = c, Vehicle = v }; 
+0

'query'를 두 번 열거하면 어떻게됩니까? 나는 두 번째로, 당신이 {6, Red, Car}, {7, Red.Bike}를 얻을 것이라고 믿는다. – Henrik

+0

@Henrik 나는 그것이 옳다고 생각한다. 반환 할 수 있습니다 .List() 그래서 그것은 한 번만 반복됩니다. – eglasius

7

또 다른 옵션은 항목의 인덱스를 포함하는 오버로드 Select method을 사용하는 것입니다. 원래 쿼리를 작성하면 다음을 사용할 수 있습니다.

var indexedQuery = query.Select((item, i) => new { Index = i + 1, Item = item }); 
foreach (var o in indexedQuery) 
{ 
    Console.WriteLine("{0},{1},{2}", o.Index, o.Item.Color, o.Item.Vehicle); 
} 
0

해결 방법 # 1 : 이것이 가장 효율적인 LINQ 형 솔루션이라고 생각합니다. 효율적으로 열거하기 위해 순열 계수를 사용합니다. , 이 하나의 현실에서 가장 효율적인 솔루션입니다 : 현실에서, 그것은

int colorCount = Enum.GetValues(typeof(Color)).Length; 
int vehicleCount = Enum.GetValues(typeof(Vehicle)).Length; 
var permutations = Enumerable 
        .Range(0, colorCount * vehicleCount) 
        .Select (index => 
           new { 
            Index = index + 1, 
            Color = (Color)(index/colorCount), 
            Vehicle = (Vehicle)(index % vehicleCount) 
            }); 

솔루션 # 2 (N ..., 0,1,2) 기본값을 변경하지 않는 열거 위해 일할 수 왜냐하면 그것은 실제로 아무것도 열거하지 않을 것이고, O (1) 솔루션을 제공하지만, (T) (객체) (int)를 수행하는 추악한 해킹을 가지고 있습니다. 위험 할 때 사용하십시오.

class Permutations<T1, T2> : IEnumerable<Tuple<int, T1, T2>> 
    where T1 : struct 
    where T2 : struct 
{ 
    int countT1 = 0; 
    int countT2 = 0; 

    public Permutations() 
    { 
     countT1 = Enum.GetValues(typeof(T1)).Length; 
     countT2 = Enum.GetValues(typeof(T2)).Length;   
    } 

    public int Length 
    { 
     get { 
      return countT1 * countT2; 
     } 
    } 

    public Tuple<int, T1, T2> this[int index] 
    { 
     get { 
      Contract.Requires(index >= 1, "Index is out of lower bounds: Options are 1 - N."); 
      Contract.Requires(index <= Length, "Index is out of upper bound.");     
      return new Tuple<int, T1, T2>(
         index, 
      /*Hack ->*/(T1)(object)((index - 1)/countT1), 
      /*Hack ->*/(T2)(object)((index - 1) % countT2)); 
     } 
    } 

    public IEnumerator<Tuple<int, T1, T2>> GetEnumerator() 
    { 
     return Enumerable.Range(1, this.Length).Select (i => this[i]).GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return this.GetEnumerator(); 
    } 
} 

void Main() 
{  
    var permutations = new Permutations<Color, Vehicle>(); 
    // Can be accesed individually: 
    var permutation = permutations[1]; 
    // Can be accesed using Enumerations 
    permutations.Dump(); // LINQPad Dump 
} 
관련 문제