Прежде всего, я не знаю, зачем вам нужен внутренний i
цикл; Является ли количество полей динамическим?
В любом случае, вернемся к вашему вопросу. Не зная, является ли ваш источник DataTables, DataReaders, Arrays и т. Д., Трудно ответить.
Но да, я помню предыдущие значения между итерациями и сбрасывал номер строки, когда текущие значения различаются.
Если используется DataTable, я обычно использую эту логику:
var dt = ...
for(var rowIndex = 0; rowIndex < dt.Rows.Count;)
{
// start of new set
var curAd = (string)dt.Rows[rowIndex]["ad"];
var curPub = (string)dt.Rows[rowIndex]["pub"];
var curLoc = (string)dt.Rows[rowIndex]["loc"];
var curDate = (DateTime)dt.Rows[rowIndex]["date"];
var line = 1;
for (; rowIndex < dt.Rows.Count;)
{
// end of set?
if (curAd != (string)dt.Rows[rowIndex]["ad"] ||
curPub != (string)dt.Rows[rowIndex]["pub"] ||
curLoc != (string)dt.Rows[rowIndex]["loc"] ||
curDate != (DateTime)dt.Rows[rowIndex]["date"])
{
break;
}
// write out current values with new line number
// ...
// get ready for next row
rowIndex++;
line++;
}
// key fields have changed, or eof, loop around to terminate or start new set as needed
}
Преимущество этого в том, что если вам нужно что-то делать в конце каждого сета, например. итоги, вы можете сделать это после того, как завершится внутренний цикл, перед циклом, чтобы начать новый набор.
Я уверен, что LINQ может сделать это тоже легко.