I know the concept of String.Split has been addressed before with a multitude of different approaches, but I am specifically interested in a LINQ solution to this question.
I've attempted to write an extension class to handle the split, but both attempts have some major issues. So for the following:
string s = "ABCDEFGHIJKLMNOPQRSTUVWX";
var results = s.SplitEvery(4);
I would want a list like:
{ "ABCD", "EFGH", "IJKL", "MNOP", "QRST", "UVWX" }
Here is my extension class:
public static class Extensions
{
public static List<string> SplitEvery(this string s, int n)
{
List<string> list = new List<string>();
var Attempt1 = s.Select((c, i) => i % n== 0 ? s.Substring(i, n) : "|").Where(x => x != "|").ToList();
var Attempt2 = s.Where((c, i) => i % n== 0).Select((c, i) => s.Substring(i, n)).ToList();
return list;
}
}
Attempt 1 inserts a dummy string "|" every time the condition isn't met, then removes all instances of the dummy string to create the final list. It works, but creating the bad strings seems like an unnecessary extra step. Furthermore, this attempt fails if the string isn't evenly divisible by n.
Attempt 2 was me trying to select only substrings where the index was divisible by N, but the 'i' value in the Select statement doesn't correspond to the 'i' value in the Where statement, so I get results like: { "ABCD", "BCDE", etc... }
I feel like I'm close to a good solution, but could use a helpful nudge in the right direction. Any suggestions?
[Edit]
I ended up going with a combination of suggestions to handle my string-splitter. It might not be the fastest, but as a newbie to LINQ, this implementation was the most succinct and easy for me to understand.
public static List<string> SplitEvery(this string s, int size)
{
return s.Select((x, i) => i)
.Where(i => i % size == 0)
.Select(i => String.Concat(s.Skip(i).Take(size))).ToList();
}
Thanks for all the excellent suggestions.
See Question&Answers more detail:
os