可以在LINQ中更改搜索方法吗?

Kry*_*lar 6 c# linq csv

我有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 :-)

svi*_*ick 2

如果您希望能够有效地使用 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 之间的行。但我假设你有这样做的原因,所以我也做了同样的事情。)