我已经创建了一个解决方案,它读取当前大小为20-30 mb的大型csv文件,我试图根据用户在运行时选择的某些列值删除重复的行,使用通常的查找重复行的技术但是看起来程序似乎根本不起作用 .
可以应用什么其他技术从csv文件中删除重复记录
这是代码,绝对是我做错了
DataTable dtCSV = ReadCsv(file, columns);
//columns is a list of string List column
DataTable dt=RemoveDuplicateRecords(dtCSV, columns);
private DataTable RemoveDuplicateRecords(DataTable dtCSV, List<string> columns)
{
DataView dv = dtCSV.DefaultView;
string RowFilter=string.Empty;
if(dt==null)
dt = dv.ToTable().Clone();
DataRow row = dtCSV.Rows[0];
foreach (DataRow row in dtCSV.Rows)
{
try
{
RowFilter = string.Empty;
foreach (string column in columns)
{
string col = column;
RowFilter += "[" + col + "]" + "='" + row[col].ToString().Replace("'","''") + "' and ";
}
RowFilter = RowFilter.Substring(0, RowFilter.Length - 4);
dv.RowFilter = RowFilter;
DataRow dr = dt.NewRow();
bool result = RowExists(dt, RowFilter);
if (!result)
{
dr.ItemArray = dv.ToTable().Rows[0].ItemArray;
dt.Rows.Add(dr);
}
}
catch (Exception ex)
{
}
}
return dt;
}
5 回答
一种方法是遍历表,构建一个包含已经存在的组合列值的
HashSet<string>
,然后你有一个重复的行 . 就像是:那应该非常快 .
如果你实现了排序例程为一对夫妇嵌套
for
或foreach
循环,你可以通过排序由你想删除重复的对列中的数据进行优化,并简单地比较每列你看着最后一排 .发布一些代码是获得更好答案的可靠方法,但不知道你是如何实现它的,你得到的任何东西都只是猜想 .
您是否尝试过在类中包装行并使用Linq?
Linq将为您提供获取不同值等的选项 .
您当前正在为每一行创建一个字符串定义的过滤条件,然后针对整个表运行它 - 这将是缓慢的 .
采用Linq2Objects方法要好得多,在这种方法中,依次将每一行读入一个类的实例,然后使用Linq Distinct运算符仅选择唯一的对象(非唯一对象将被抛弃) .
代码看起来像:
如果您不知道CSV文件将具有的字段,那么您可能需要稍微修改它 - 可能使用将CSV单元格读入每行的列表或字典的对象 .
使用Linq从文件中读取对象时,某人或其他人的这篇文章可能有所帮助 - http://www.developerfusion.com/article/84468/linq-to-log-files/
基于新代码,你提供了第二个答案 - 我仍然更喜欢第一个答案,但如果你必须使用
DataTable
和DataRows
,那么第二个答案可能有所帮助: