使用LINQ填充List <object>

时间:2016-05-13 15:09:27

标签: c# linq

我有一个这样的文件:

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);

并分别在oddLinesevenLines分别成功检索地址和名称行。

我想要什么

我应该使用LINQ填充objectsList,而不是使用循环

逐个填充它们

非常感谢你的帮助

4 个答案:

答案 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)和从进行拆分的数组索引中拉出。

请注意,如果文件与格式不匹配,则会产生不正确的结果,例如,如果文件的行数为奇数,则namecity对于最后一个条目是相同的如果奇数行没有至少两个管道符,则countryphone为空。

我还使用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]});                

ZipoddLines的每一行与evenLines的相应行组合在一起。第二行按|拆分,每个组合生成一个新的Person对象并填充其数据。

当然应该有更多的错误处理,因为如果您的文件中缺少值,这可能会抛出异常。

答案 2 :(得分:1)

为了更好地分离问题,您可以先在oddLinesevenLines中合并两个结果,以创建完整的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();
    }
}
相关问题