list in list在单个linq查询中



我有这个csv

<表类> Id 名称 年龄 tbody><<tr>1亚历克斯201玛丽亚16

为了提高性能和缩短代码,我们可以做的一件大事是避免过于频繁地调用.ToList()。事实上,如果您可以接受IEnumerable<string[]>而不是List<List<string>>,我们可以将其降低到这一点,这也应该运行得更快并分配MUCH更少的内存:

var data = file.Skip(1).Select(line => line.Split(';'));

如果你真的必须List<List<string>>,我们可以调整它如下:

var data = file.Skip(1).Select(line => line.Split(';').ToList()).ToList();

但是再次:每次调用.ToList()都会增加程序的RAM和CPU使用。最好等得越久越好。


我也很好奇file变量是从哪里来的。这似乎是File.ReadAllLines()File.ReadLines()的结果,我可以告诉你,后者将再次是MUCH这比前者更有效。

你想要这样写:

var header = File.ReadLines("...").Take(1);
var data = File.ReadLines("...").Skip(1).Select(line => line.Split(';'));
注意,此时data还没有读取文件。但是,您可以在foreach循环或linq扩展中使用它,它将以实时的方式读取文件,这样每次只需要文件中的一行到内存中。

这是更有效的,甚至当你最终将在屏幕上显示整个文件内容或以其他方式完全加载文件,因为它允许你节省RAM(和CPU),同时将原始数据从文件转换成你想要显示或其他目的的最终结构。


与所有这些分开,你可以做的事情来真正提高性能是从NuGet获得一个专用的csv解析器,特别是当.Split()被认为是有点慢,并且在许多边缘情况下失败。

当然-就用.Select:

var data = predata.Select(p = > p.Split(';'));

这实际上会给你一个IEnumerable<string[]>,你可以迭代。如果您需要列表,只需在每个级别添加ToList:

var data = predata.Select(p = > p.Split(';').ToList()).ToList();

你可以跳过predata,只需将其更改为file.Skip(1)(如果你所做的只是迭代,则不需要在Skip之后调用ToList)。

试试这个:

var data=file.select(x=>x.Split(';').ToList()).ToList();

最新更新