有没有更简洁的方法将分隔文本拆分为数据结构?

时间:2013-01-22 12:22:17

标签: c# arrays linq text

我有这段代码:

    private IEnumerable<FindReplacePair> ConstructFindReplacePairs(string inputFilePath)
    {
        var arrays = from line in File.ReadAllLines(Path.GetFullPath(inputFilePath))
                    select line.Split('|');

        var pairs = from array in arrays
                    select new FindReplacePair { Find = array[0], Replace = array[1] };

        return pairs;
    }

我想知道是否有一个干净的linq语法只在一个查询中执行此操作,因为它感觉应该有。

我尝试链接from子句(一个SelectMany),但是它过多地分割了数据,我无法进入单独的数组进行选择(而是我一次只能获得一个字符串)。

3 个答案:

答案 0 :(得分:4)

IEnumerable<FindReplacePair> ConstructFindReplacePairs(string inputFilePath)
{
    return File.ReadAllLines(Path.GetFullPath(inputFilePath))
               .Select(line => line.Split('|'))
               .Select(array => new FindReplacePair { 
                          Find = array[0], 
                          Replace = array[1] 
                });
}

OR

IEnumerable<FindReplacePair> ConstructFindReplacePairs(string inputFilePath)
{
    return from line in File.ReadAllLines(Path.GetFullPath(inputFilePath))
           let array = line.Split('|')
           select new FindReplacePair {
              Find = array[0], Replace = array[1]
           };
}

您还可以添加 where 条件,以检查数组是否包含多个元素。

答案 1 :(得分:2)

不确定这是否更清洁,只是更短一些。

IEnumerable<FindReplacePair> allFindReplacePairs = File.ReadLines(inputFilePath)
    .Select(l => new FindReplacePair { Find = l.Split('|')[0], Replace = l.Split('|')[1] });

请注意,我正在使用File.ReadLines,它不需要先将所有行读入内存。它就像一个StreamReader

答案 2 :(得分:0)

当归结为美化LINQ时,我通常会写出简单的循环,而Resharper会建议更好的LINQ优化,例如

foreach (var split in File.ReadAllLines(inputFilePath).Select(l => l.Split('|')))
    yield return new FindReplacePair { Find = split[0], Replace = split[1] };

R#将其转换为

return File.ReadAllLines(inputFilePath).Select(l => l.Split('|')).Select(split => new FindReplacePair { Find = split[0], Replace = split[1] });

那说你不妨使用内置类型,例如.ToDictionary(l => l[0], l => l[1])或在FindReplacePair上添加方法,即

return File.ReadAllLines(inputFilePath).Select(l => l.Split('|')).Select(FindReplacePair.Create);

public static FindReplacePair Create(string[] split)
{
    return new FindReplacePair { Find = split.First(), Replace = split.Last() };
}