2017-02-27 138 views
0

第一次發佈,所以原諒我格式化... 我有一個文本文件,我讀過使用File.ReadLines()和順序存儲到名單。 然後我想找到以「Student」開頭的第一個字符串實例。然後,我想將列表中的所有字符串都放到以「Student」開頭的字符串的下一個實例上,然後停在它之前。將這些字符串複製到子列表中,然後沖洗並重復,直到文件結束。文本文件的從字符串列表創建基於字符串的子列表開始於

例子:

東西就行1

東西就行2

學生 ...:張三

標識... :12345

主要...:數學

數目不詳的多線

學生 ...:珍妮·史密斯

...編號:54321

主要...:護理

多行

學生 ...:李四

...編號:11223

專業:解剖學

更行。

我想每個學生的行列表看起來像這樣:

學生1個

學生...:張三

...編號:12345

重大...:數學

未知數的更多行數

學生2

學生...:珍妮·史密斯

...編號:54321

主要...:護理

多行

我已經使用了foreach來行。每一行都被添加到一個新列表中。當我找到一個以「Student」開頭的字符串時,我創建一個新的學生對象並將這些行存儲在子列表中。然後我清除子列表,然後繼續使用foreach,創建新的學生對象。

當前問題 我想念最後一個學生。我知道我可以使用if語句來檢查當前行是否以「Student」開頭,包括檢查當前行是否是列表中的最後一行,但我覺得必須有一個更好/更快的方法來執行此操作。
我必須添加& & lines.Count> 3,因爲在我想要跳過的第一個「Student」實例之前有幾行。

Linq的例子將不勝感激。

List<Student> students = new List<Student>(); 
List<string> lines = File.ReadLines(args[0]).ToList(); 
List<string> student_lines = new List<string>(); 
foreach(string line in lines) 
{ 
    if(line.StartsWith("Student...", StringComparison.OrdinalIgnoreCase) && lines.Count > 3) 
    { 
     students.Add(new Student(student_lines)); 
     student_lines.Clear(); 
    } 
    lines.Add(line) 
} 
+0

容易'File.ReadAllText',各執「學生」,並通過'\ r \ n'分割零件 – Slai

+0

可以詳細說明拆分關於「學生」? – user1546185

回答

1

試試這個:

var results = 
    lines 
     .Aggregate(new[] { new List<string>() }.ToList(), (a, x) => 
     { 
      if (x.StartsWith("Student")) 
      { 
       a.Add(new List<string>()); 
      } 
      a.Last().Add(x); 
      return a; 
     }) 
     .Skip(1) 
     .Select(x => new Student(x)) 
     .ToList(); 

從你的樣本數據,我得到這樣的:

result

+0

這就是我要找的。我已經與C#一段時間了,所以我會看看這裏發生了什麼。感謝您的輸入! – user1546185

+0

夢幻般的工作!這正是我想要的。很棒! – user1546185

-1

這是真的模糊你想要做的,但這是一個非常基本的例子,我認爲你在做什麼。

現在你唯一需要做的就是改變fileName的參數。

static void Main(string[] args) 
{ 
    string line = null; 
    Student student = null; 
    IList<Student> students = new List<Student>(); 
    using (var fileReader = new StreamReader(fileName)) 
    { 
     while ((line = fileReader.ReadLine()) != null) 
     { 
      if (string.IsNullOrWhiteSpace(line)) 
       continue; //continue execution on extra lines 
      if(line.StartsWith("Student...", StringComparison.CurrentCultureIgnoreCase)) 
      { 
       student = new Student(); 
       students.Add(student); 
      } 

      if (student != null) 
       student.Lines.Add(line); 


     } 

     fileReader.Close(); 
    } 
} 

class Student 
{ 
    public IList<string> Lines { get; } = new List<string>(); 
} 

簡而言之所有這個小程序確實是開始逐行讀取文件中的行(注意while ((line = fileReader.ReadLine()) != null)會的line值設置到文件或null下一行時,該文件已被完全讀取。

接下來它會檢查空行(我們不關心的空行,所以我們繼續前進)

然後我們檢查,如果line startsith Student...我們現在用StringComparison.CurrentCultureIgnoreCase所以我們可以比較不區分大小寫。

如果這是一個學生行,我們然後創建一個新學生,並Add()它到我們的students集合。

最後只要student不爲空,我們可以將line的內容添加到學生.Lines屬性中。

+0

不知道爲什麼downvote。謝謝(你的)信息。我從這個方法開始,但決定輸入文本文件不是那麼大(也許10萬行),並且ReadLines()函數是我想要使用的。 – user1546185

0

像這樣的事情

if (args.Length < 1) return;    // optional check if any args 

string text = File.ReadAllText(args[0]); 

string[] parts = text.Split(new[] { "Student" }, 0); 

string[][] lines = Array.ConvertAll(parts, part => part.Split(new[] { '\r', '\n' }, 1)); 

Debug.Print(lines[1][1]);  // "Id...: 12345"