我使用StreamReader访问CSV文本文件并将所有行读取到DataTable。
public static DataTable ConvertToDataTable(string filePath, int numberOfColumns)
{
DataTable tbl = new DataTable();
for (int col = 0; col < numberOfColumns; col++)
tbl.Columns.Add(new DataColumn("Column" + (col + 1).ToString()));
string line;
System.IO.StreamReader file = new StreamReader("C:/ProgramData/3CX/Instance1/Data/Logs/CDRLogs/cdr.log");
while ((line = file.ReadLine()) != null)
{
var cols = line.Split(',');
DataRow dr = tbl.NewRow();
for (int cIndex = 0; cIndex < cols.Length + 1; cIndex++)
{
dr[cIndex] = cols[cIndex];
}
tbl.Rows.Add(dr);
}
一旦我将所有CSV行添加到DataTable,我想迭代行并在条件下删除不需要的行。
DataTable dt = ConvertToDataTable("C:/ProgramData/3CX/Instance1/Data/Logs/CDRLogs", 4);
for (int i = 0; i < dt.Rows.Count; i++)
{
string duration = dt.Rows[i][1].ToString();
if (duration == "")
{
dt.Rows[i].Delete();
}
Console.WriteLine(i.ToString() + dt.Rows[i][1].ToString());
}
这样运行得很好,直到我到达最后一行,它似乎循环通过一条不存在的行。
任何人都知道为什么?任何和所有的帮助将不胜感激!
答案 0 :(得分:4)
您可以向后迭代这些行以保持索引不变。
for(int i = dt.Rows.Count - 1; i >= 0; i--)
{
dt.Rows[i].Delete();
}
答案 1 :(得分:3)
删除时,循环后退,而不是:
for (int i = 0; i < dt.Rows.Count; i++)
{
...
dt.Rows[i].Delete();
...
}
把
for (int i = dt.Rows.Count - 1; i >= 0 ; --i)
{
string duration = dt.Rows[i][1].ToString();
if (duration == "")
{
dt.Rows[i].Delete();
}
Console.WriteLine(i.ToString() + dt.Rows[i][1].ToString());
}
如果因任何原因必须循环转发,请将循环修改为
for (int i = 0; i < dt.Rows.Count; ) // do not increment here
{
string duration = dt.Rows[i][1].ToString();
if (duration == "")
{
dt.Rows[i].Delete();
}
else
i += 1; // ... but increment here
Console.WriteLine(i.ToString() + dt.Rows[i][1].ToString());
}
答案 2 :(得分:2)
删除行时,不应设置i = i + 1,因为数量或行减少了
int i = 0;
while(i < dt.Rows.Count)
{
string duration = dt.Rows[i][1].ToString();
if (duration == "")
{
dt.Rows[i].Delete();
}
else
{i++;}
Console.WriteLine(i.ToString() + dt.Rows[i][1].ToString());
}
答案 3 :(得分:1)
循环结束时增加for (int i = 0; i < dt.Rows.Count; )
{
string duration = dt.Rows[i][1].ToString();
if (duration == "")
{
dt.Rows[i].Delete();
}
else
{
i++;
}
Console.WriteLine(i.ToString() + dt.Rows[i][1].ToString());
}
{{1}}
答案 4 :(得分:1)
当我必须从集合中删除元素时,我通常会做的事情是迭代将行删除保存在不同的集合中。 对于你的情况,这样的事情:
int i = 0; // if you need to dump also the number of the row
List<DataRow> toDelete = new List<DataRow>();
foreach (var row in dt.Rows)
{
string duration = row[1].ToString();
if (duration == "")
{
toDelete.Add(row);
}
Console.WriteLine(i.ToString() + row[1].ToString());
i++;
}
foreach (var rowToDelete in toDelete)
row.Delete();
答案 5 :(得分:0)
DataTable dt = ConvertToDataTable(“C:/ ProgramData / 3CX / Instance1 / Data / Logs / CDRLogs”,4);
for (int i = 0; i < dt.Rows.Count; i++)
{
string duration = dt.Rows[i][1].ToString();
if (duration == "")
{
dt.Rows[i].Delete();
continue; //Not printing deleted objects. So line after IF block won'nt exist.
}
Console.WriteLine(i.ToString() + dt.Rows[i][1].ToString());
}