我有一个这样的文件:
City|Country|Phone Number
Name
City|Country|Phone Number
Name
City|Country|Phone Number
Name
依旧......
我已经上课了:
class Person
{
string city, country, phone, name;
}
在阅读这个大文件后,我想创建一个List并将所有值放在各自的字段中。
到目前为止我的工作
List<PersonObj> objectsList = new List<PersonObj>();
string[] peopleFile = System.IO.File.ReadAllLines(fileName);
var oddLines = peopleFile.Where((src, index) => index % 2 != 0);
var evenLines = peopleFile.Where((src, index) => index % 2 == 0);
并分别在oddLines
和evenLines
分别成功检索地址和名称行。
我想要什么
我应该使用LINQ填充objectsList,而不是使用循环
逐个填充它们非常感谢你的帮助
答案 0 :(得分:2)
这应该做你想要的事情
var people = File.ReadLines(fileName)
.Select((l,i) => new { Line = l.Split('|'), LineNo = i })
.GroupBy(x => x.LineNo/2)
.Select(grp => new Person
{
city = grp.First().Line[0],
country = grp.First().Line.Skip(1).FirstOrDefault(),
phone = grp.First().Line.Skip(2).FirstOrDefault(),
name = grp.Last().Line[0]
})
.ToList();
基本上你使用Select
的重载给你索引,这将允许你按行号分组,这样你就可以获得前两行的组,接下来的两行,依此类推。然后从组中的第一行或最后一行(应该只有2)和从进行拆分的数组索引中拉出。
请注意,如果文件与格式不匹配,则会产生不正确的结果,例如,如果文件的行数为奇数,则name
和city
对于最后一个条目是相同的如果奇数行没有至少两个管道符,则country
或phone
为空。
我还使用File.ReadLines
而不是File.ReadAllLines
来避免创建不需要的中间数组。
答案 1 :(得分:1)
您可以使用Zip
执行此操作。我假设evenLines
包含城市等,oddLines
包含名称。
var persons = oddLines.Zip(
evenLines.Select(line => line.Split('|')),
(name, data) => new Person {name = name, city = data[0], country = data[1], phone = data[2]});
Zip
将oddLines
的每一行与evenLines
的相应行组合在一起。第二行按|
拆分,每个组合生成一个新的Person
对象并填充其数据。
当然应该有更多的错误处理,因为如果您的文件中缺少值,这可能会抛出异常。
答案 2 :(得分:1)
为了更好地分离问题,您可以先在oddLines
和evenLines
中合并两个结果,以创建完整的string
:
var lines = from o in oddLines
from ev in evenLines
select o + "|" + ev;
然后使用双LINQ
Select
:
objectsList = lines.Select(x => x.Split('|'))
.Select(y => new PersonObj() {
city = y[0],
country = y[1],
phone = y[2],
name = y[3],
}).ToList();
第一个Select
将用于将文件中的每一行拆分为string[]
,其中包含4个元素,第二个Select
用于从中创建PersonObj
项。
请注意,您必须将字段(city, country, phone, name
)设为public
而不是private
才能执行此操作。
答案 3 :(得分:1)
这是一种LINQ方式:
class Person
{
public string Name { get; set; }
public string Country { get; set; }
public string City { get; set; }
public string PhoneNumber { get; set; }
}
class Program
{
static void Main(string[] args)
{
string[] lines = File.ReadAllLines("data.txt");
List<Person> people =
lines
.Select((line, index) =>
new
{
Index = index / 2,
RawData = line
}
)
.GroupBy(obj => obj.Index)
.Select(group =>
{
var rawPerson = group.ToArray();
string name = rawPerson[1].RawData;
string[] rawDetails = rawPerson[0].RawData.Split('|');
return
new Person()
{
Name = name,
City = rawDetails[0],
Country = rawDetails[1],
PhoneNumber = rawDetails[2]
};
}
)
.ToList();
}
}