我有這個 csv
| ID | 姓名 | 年齡 |
|---|---|---|
| 1 | 亞歷克斯 | 20 |
| 1 | 瑪麗亞 | 16 |
我想制作一個 CSV 閱讀器,將 csv 拆分為元素header和data.
Header只是一個字串陣列,可以保存標題并且運行良好。
我在保存data. 我想將 csv 保存在沒有標題的串列串列中,這就是我的做法:
var predata = file
.Skip(1)
.ToList();
List<List<string>> data = new List<List<string>>();
for (int i = 0; i < predata.Count; i )
{
List<string> templist = predata[i]
.Split(';')
.ToList();
data.Add(templist);
}
這看起來效率很低,我想知道是否有任何方法可以做到這一點,但要短得多。甚至可能在一個 linq 查詢中。
請不要報告這個問題,我會盡力解釋我的問題
uj5u.com熱心網友回復:
為了提高性能和縮短代碼,我們可以做的一件大事是避免呼叫.ToList()過于頻繁。事實上,如果你能接受IEnumerable<string[]>而不是List<List<string>>我們可以把它歸結為這一點,它也應該運行得更快并分配更少的記憶體:
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()or的結果File.ReadLines(),我可以告訴你,后者將再次比前者更有效率。
所以你想要這樣的東西:
var header = File.ReadLines("...").Take(1);
var data = File.ReadLines("...").Skip(1).Select(line => line.Split(';'));
注意此時data 尚未通讀該檔案。但是,您可以在foreach回圈中使用它或使用 linq 擴展名,它會以即時方式讀取檔案,這樣一次只需要檔案中的一行在記憶體中。
這更有效,即使您最終將在螢屏上顯示整個檔案內容或以其他方式完全加載檔案,因為它允許您在將原始資料從檔案轉換為您想要的最終結構時節省 RAM(和 CPU)用于展示或其他目的。
與所有這些不同,您可以做的真正提高性能的事情是從 NuGet 獲得一個專用的 csv 決議器,尤其.Split()是眾所周知的慢一點并且在許多邊緣情況下都會失敗。
uj5u.com熱心網友回復:
當然 - 只需使用.Select:
var data = predata.Select(p = > p.Split(';'));
這實際上會給你一個IEnumerable<string[]>你可以迭代的。如果您需要串列,只需ToList在每個級別添加:
var data = predata.Select(p = > p.Split(';').ToList()).ToList();
predata您可以通過將其更改為跳過(如果您所做的只是迭代,則file.Skip(1)無需呼叫)。ToListSkip
uj5u.com熱心網友回復:
試試這個:
var data=file.select(x=>x.Split(';').ToList()).ToList();
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/465760.html
