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
}