我有3万行的csv文件.我必须根据许多条件选择许多值,因此在许多循环和"如果"的情况下我决定使用linq.我写了一堂课来读csv.它实现了IEnumerable以与linq一起使用.这是我的普查员:
class CSVEnumerator : IEnumerator
{
private CSVReader _csv;
private int _index;
public CSVEnumerator(CSVReader csv)
{
_csv = csv;
_index = -1;
}
public void Reset(){_index = -1;}
public object Current
{
get
{
return new CSVRow(_index,_csv);
}
}
public bool MoveNext()
{
return ++_index < _csv.TotalRows;
}
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,但速度很慢.假设我想在范围100; 150行中选择A列中的最大值.
max = (from CSVRow r in csv where r.ID > 100 && r.ID < 150 select r).Max(y=>y["A"]);
Run Code Online (Sandbox Code Playgroud)
这将工作,但linq搜索30 000行而不是48的最大值.正如我所说,我可以使用循环,但只有在这个示例情况下,条件是"残酷的":)
有没有办法覆盖linq集合搜索.类似于:查看我的枚举器上使用的查询,看看,如果"where"中的任何linq条件包含"行ID过滤器",并根据此提供另一个数据.
我不想将部分数据复制到另一个数组/集合,问题不在我的csv阅读器中.通过id访问每一行很快,唯一的问题是当你访问所有这30 000个时.任何帮助appriciated :-)
如果您希望能够有效地使用 LINQ 来实现此目的,则需要使用表达式树,其方式与 SQL 数据库的各种 LINQ 提供程序类似(但简单得多)。虽然可行,但我认为对于这样一个简单的任务来说,需要相当多的代码。
因此,我认为更好的解决方案是使用单独的方法来选择所需的行(然后可能使用 LINQ 来处理结果)。
此外,许多返回集合的操作(包括您的原始代码和我的修改)可以通过使用迭代器方法来简化。
因此,您的代码可能如下所示:
public static IEnumerable<CSVRow> GetRows(
this CSVReader reader, int idGreaterThan, int idLessThan)
{
for (int i = idGreaterThan + 1; i < idLessThan; i++)
{
yield return new CSVRow(reader, i);
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,它是 的扩展方法CSVReader,但另一个解决方案(例如该类的实际方法)可能更适合您。
您的示例将类似于:
max = csvReader.GetRows(100, 150).Max(y => y["A"]);
Run Code Online (Sandbox Code Playgroud)
(另外,我觉得很奇怪,当你有限制 100 和 150 时,你实际上想要 101 到 149 之间的行。但我假设你有这样做的原因,所以我也做了同样的事情。)
| 归档时间: |
|
| 查看次数: |
265 次 |
| 最近记录: |