C# C LINQ自动生成的编号或索引

C# C LINQ自动生成的编号或索引,c#,linq,C#,Linq,推导组合时,生成自动生成数字的可能方法是什么 public enum Color { Red,Green,Blue } public enum Vehicle { Car,Bike } i、 e{Red,Car},{Red,Bike},{Green,Car},{Green,Bike} 乔恩·斯基特帮我解决了这个问题 现在我想要这样的组合 {1,Red,Car},{2,Red,Bike},{3,Green,Car},{4,Green,Bike},{5,Blue,Car},{6,

推导组合时,生成自动生成数字的可能方法是什么

public enum Color
{
    Red,Green,Blue
}

public enum Vehicle
{
    Car,Bike
}
i、 e{Red,Car},{Red,Bike},{Green,Car},{Green,Bike}

乔恩·斯基特帮我解决了这个问题

现在我想要这样的组合

{1,Red,Car},{2,Red,Bike},{3,Green,Car},{4,Green,Bike},{5,Blue,Car},{6,Blue,Bike}
生成自动编号的方法是什么?

试试:

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 };

另一种选择是使用包含项索引的重载。基于原始查询,您可以使用以下方法:

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);
}

解决方案1:我相信这是最有效的类似LINQ的解决方案。它使用置换计数进行有效枚举;实际上,它可以用于任何不更改默认值0,1,2,。。n

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: 这一个实际上是最有效的解决方案,因为它实际上不会枚举任何东西,给你一个O1解决方案,但它有一个丑陋的hack在那里做Tobjection。使用风险自负

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
}

当您枚举查询两次时,会发生什么情况?我相信,第二次,你得到{6,Red,Car},{7,Red.Bike},@Henrik,我想这是对的,现在不能检查它,所以如果它是你返回的东西,你可以查询。ToList,所以它只迭代一次。表达式树可能不包含赋值operator@klent如果你是说你明白了,也许你是在不同的背景下使用它,类似于用于从db读取的表达式。是这样吗?@eglasius我从数据库中调用它,然后在select new{counter=ctr++}中添加计数器
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
}