我有这个for循环。 TicketList以109张票开头。 nColumns = 100.我根据票数计算我需要的行数。所以在这种情况下我需要2行。第一行将满,第二行仅有9个条目。我有下面的循环。它只为NumOfRows运行一次并填充前100个并且从不循环。
我错过了什么?
for (int j = 0; j < NumOfRows; j++)
{
for (int i = 0; i < nColumns; i++)
{
if (TicketList.Count() > 0)
{
t = rand.Next(0, TicketList.Count() - 1);
numbers[i, j] = TicketList[t];
TicketList.Remove(TicketList[t]);
}
}
}
答案 0 :(得分:3)
尝试更改代码以使用更类似LINQ的功能方法。如果可能使逻辑更容易。像这样:
TicketList
.OrderBy(x => rand.Next())
.Select((ticket, n) => new
{
ticket,
j = n / NumOfRows,
i = n % NumOfRows
})
.ToList()
.ForEach(x =>
{
numbers[x.i, x.j] = x.ticket;
});
您可能需要翻转x.i
&amp; x.j
或使用nColumns
代替NumOfRows
- 我不确定您的逻辑是什么 - 但此代码可能会更好。
答案 1 :(得分:1)
除了一些糟糕的选择,你的循环看起来很好。我敢说NumOfRows
没有正确计算。
表达式NumOfRows = (TotalTickets + (Columns - 1)) / Columns;
应该计算正确的行数。
此外,您应使用Count
的属性版本而不是Linq扩展方法,并使用IList<T>.RemoveAt()
或List<T>.RemoveAt
而不是Remove(TicketList[T])
。
使用Remove()
要求枚举列表以找到要删除的元素,这可能与您要定位的索引不同。更不用说当您已经知道要删除的正确索引时,您将扫描每个删除调用的列表的50%(平均)。
前面列出的功能方法看起来有点矫枉过正。
我假设有关使用的各种变量的某些事实,我试图复制您的问题。循环重复预期的次数。
static void TestMe ()
{
List<object> TicketList = new List<object>();
for (int index = 0; index < 109; index++)
TicketList.Add(new object());
var rand = new Random();
int nColumns = 100;
int NumOfRows = (TicketList.Count + (nColumns - 1)) / nColumns;
object[,] numbers;
int t;
numbers = new object[nColumns, NumOfRows];
for (int j = 0; j < NumOfRows; j++)
{
Console.WriteLine("OuterLoop");
for (int i = 0; i < nColumns; i++)
{
if (TicketList.Count > 0)
{
t = rand.Next(0, TicketList.Count - 1);
numbers[i, j] = TicketList[t];
TicketList.RemoveAt(t);
}
}
}
}
您所看到的问题必须是您未在样本中包含的内容的结果。