2013-10-31 75 views
0

我嘗試使用Linq讀取簡單的TXT文件,但是,我的dificult是。通過2線讀取2文件,爲此,我做了一個簡單的功能,但是,我相信我可以閱讀TXT的2分2行...使用Linq讀取2行2行2

我的代碼讀取文本行是:

private struct Test 
    { 
     public string Line1, Line2; 
    }; 

    static List<Test> teste_func(string[] args) 
    { 
     List<Test> exemplo = new List<Test>(); 
     var lines = File.ReadAllLines(args[0]).Where(x => x.StartsWith("1") || x.StartsWith("7")).ToArray(); 

     for(int i=0;i<lines.Length;i++) 
     { 
      Test aux = new Test(); 
      aux.Line1 = lines[i]; 
      i+=1; 
      aux.Line2 = lines[i]; 

      exemplo.Add(aux); 
     } 

     return exemplo; 
    } 

之前,我創建這個功能,我試着這樣做:

var lines = File.ReadAllLines(args[0]). .Where(x=>x.StartsWith("1") || x.StartsWith("7")).Select(x => 
       new Test 
       { 
        Line1 = x.Substring(0, 10), 
        Line2 = x.Substring(0, 10) 
       }); 

但是,很明顯,該系統將通過線得到線,併爲行一個新的結構... 所以,我怎麼能用linq獲得2乘2行?

---編輯 也許有可能創建一個新的'linq'功能,以使該???

Func<T> Get2Lines<T>(this Func<T> obj....) { ... } 
+0

我跑的程序,並瞭解它獲得開始的行1或7的結果被返回爲與2個特性的單一結構。我不明白「通過2行LINQ」?你想解決什麼問題?你只是想把兩條線連成一條?如果是這樣,只需將另一個屬性添加到Struct中即可。當你在它時,使結構不可變。 –

回答

1

像這樣的事情?

public static IEnumerable<B> MapPairs<A, B>(this IEnumerable<A> sequence, 
               Func<A, A, B> mapper) 
    { 
     var enumerator = sequence.GetEnumerator(); 
     while (enumerator.MoveNext()) 
     { 
      var first = enumerator.Current; 
      if (enumerator.MoveNext()) 
      { 
       var second = enumerator.Current; 
       yield return mapper(first, second); 
      } 
      else 
      { 
       //What should we do with left over? 
      } 
     } 
    } 

然後

File.ReadAllLines(...) 
    .Where(...) 
    .MapPairs((a1,a2) => new Test() { Line1 = a1, Line2 = a2 }) 
    .ToList(); 
+0

謝謝,但是,如何正確使用你的功能? – Alexandre

+0

非常感謝:) – Alexandre

+0

這是一個linq擴展方法,你只需要提供一個方法,它需要兩個'A'(它們是字符串,如果它們是文件的行)並返回一個'B'鍵入'Test') – Rob

1
File.ReadLines("example.txt") 
    .Where(x => x.StartsWith("1") || x.StartsWith("7")) 
    .Select((l, i) => new {Index = i, Line = l}) 
    .GroupBy(o => o.Index/2, o => o.Line) 
    .Select(g => new Test(g)); 

public struct Test 
{ 
    public Test(IEnumerable<string> src) 
    { 
     var tmp = src.ToArray(); 
     Line1 = tmp.Length > 0 ? tmp[0] : null; 
     Line2 = tmp.Length > 1 ? tmp[1] : null; 
    } 

    public string Line1 { get; set; } 
    public string Line2 { get; set; } 
} 
+0

你的代碼是非常有趣的,但'新的測試(g)',不工作,結構不會收到構造函數的參數...我如何使用你的方法? – Alexandre

+1

@Alexandre一個結構體可以有一個帶參數的構造函數。它不能有無參數的構造函數。我將代碼更改爲struct。如果你不喜歡構造函數,你總是可以將代碼嵌入最後一個'Select'中,但對我來說這更乾淨。 –

+0

THANKs :) ...順便說一句,如果我有更多的線,例如7行? – Alexandre