Is there a cleaner way to split delimited text into data structures?

I have this code:

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

I am wondering if there is pure linq syntax to perform this operation in only one query, because it seems to be there.

I tried linking sentences from (selectMany), but it parses the data too much, and I could not get to the individual arrays for selection (instead, I got separate rows one at a time).

+4
source share
3 answers
 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] }; } 

You can also add where condition to check if the array has more than one element.

+4
source

Not sure if it's cleaner, a little shorter.

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

Note that I am using File.ReadLines , which does not have to read all the lines in memory first. It works as a StreamReader .

+2
source

When it comes to the LINQ prefix, I usually write a simple loop, and Resharper will offer better LINQ optimizations, for example.

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

R # converts it to

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

However, you can use the built-in type, for example. .ToDictionary(l => l[0], l => l[1]) or add a method on FindReplacePair , i.e.

 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() }; } 
0
source

All Articles