代码之家  ›  专栏  ›  技术社区  ›  user215675

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

  •  2
  • user215675  · 技术社区  · 16 年前

    在派生组合时,生成自动生成数字的可能方法是什么?

    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}
    

    生成自动编号的方法是什么?

    3 回复  |  直到 14 年前
        1
  •  5
  •   eglasius    16 年前

    尝试:

    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 };
    
        2
  •  7
  •   Ahmad Mageed    16 年前

    另一种选择是使用重载 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);
    }
    
        3
  •  0
  •   Marcel Valdez Orozco    14 年前

    解决方案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: 这一个实际上是最有效的解决方案,因为它实际上不会列举任何东西,给你一个O(1)的解决方案,但它有一个丑陋的黑客那里有(t)(对象)(in t)。风险自负。

    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
    }