2013-10-31 45 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