C# 使用Linq 2乘2行读取文件
我尝试使用Linq读取一个简单的TXT文件,但是,我的困难是。读取一个2乘2行的文件,为此,我做了一个简单的函数,但是,我相信我可以读取分隔2乘2行的TXT 我阅读文本行的代码是:C# 使用Linq 2乘2行读取文件,c#,linq,C#,Linq,我尝试使用Linq读取一个简单的TXT文件,但是,我的困难是。读取一个2乘2行的文件,为此,我做了一个简单的函数,但是,我相信我可以读取分隔2乘2行的TXT 我阅读文本行的代码是: private struct Test { public string Line1, Line2; }; static List<Test> teste_func(string[] args) { List<Test>
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;
}
但是,很明显,该系统将逐行获取,并为该行创建一个新的结构。。。
那么,我怎样才能用linq得到2乘2的直线呢
---编辑
也许有可能创建一个新的“linq”函数来实现它
Func get2line(此函数对象…){…}
像这样的东西
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.ReadLines(“example.txt”)
其中(x=>x.StartsWith(“1”)| | x.StartsWith(“7”))
.Select((l,i)=>new{Index=i,Line=l})
.GroupBy(o=>o.Index/2,o=>o.Line)
.选择(g=>新测试(g));
公共结构测试
{
公共测试(IEnumerable src)
{
var tmp=src.ToArray();
Line1=tmp.Length>0?tmp[0]:空;
Line2=tmp.Length>1?tmp[1]:空;
}
公共字符串Line1{get;set;}
公共字符串第2行{get;set;}
}
我运行了该程序,并了解它会获得以1或7开头的行。结果作为带有2个属性的单个结构返回。我不明白“2乘2线与linq”?你想解决什么问题?您只是想将这两行连接成一行吗?如果是这样的话,只需将另一个属性添加到结构中即可。这是一个linq扩展方法,您只需要提供一个方法,该方法接受两个a
s(如果它们是文件的行,则为字符串)并返回一个B
(类型为Test
)的对象@Rob它不是linq方法。它只是您编写的一个自定义扩展方法,模拟LINQ方法中的特定编程风格。LINQ只是System.LINQ命名空间中的类。请注意,您应该真正使用ReadLines
而不是ReadAllLines
,最好不要调用ToList
,除非确实需要允许行流式传输,而不是急切地加载到内存中。@Servy:是-公平点。我通常会使用ReadLines
并省略ToList
,但我在模拟问题中的用法,其中原始示例返回一个列表。谢谢:)。。。顺便说一句,如果我有更多的行,例如7行?你的代码很有趣,但是,“新测试(g)”,不起作用,结构没有收到构造函数的参数。。。我如何使用你的方法?@Alexandre一个结构可以有一个带参数的构造函数。它不能有无参数构造函数。我把代码改为struct。如果你不喜欢构造函数,你可以将代码内联到最后一个选择,但对我来说这更干净。谢谢:)。。。顺便说一句,如果我有更多的行,例如7行?@Alexandre只需将行o.Index/2
更改为o.Index/7
,并修改测试结构及其构造函数。
Func<T> Get2Lines<T>(this Func<T> obj....) { ... }
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();
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; }
}