Reputation: 64208
In C#, calling the .Split
method will split a string into an array of strings based on some character or string.
Is there an equivalent method for lists or arrays?
For example:
var foo = new List<int>() { 1, 2, 3, 0, 4, 5, 0, 6 };
var output = Split(foo, 0);
// produces { { 1, 2, 3 }, { 4, 5 }, { 6 } }
This is what I have so far -- is there a cleaner or more eloquent way of accomplishing the same task?
IEnumerable<IEnumerable<T>> Split<T>(IEnumerable<T> list, T divider)
{
var output = new List<List<T>>();
var temp = new List<T>();
foreach ( var item in list )
{
if (item.Equals(divider))
{
output.Add(temp);
temp = new List<T>();
}
else
{
temp.Add(item);
}
}
output.Add(temp);
return output;
}
Edit:
It just occurred to me that my version will split the list only by a single element, whereas string.Split
can split using either a single character, or an arbitrary string.
Just for the sake of completeness, what would be the best way to implement that?
Upvotes: 7
Views: 473
Reputation: 898
Don't know of any built-in function. However, I would consider doing this:
public static IEnumerable<List<int>> Split(List<int> list, int delimiter)
{
var start = 0;
foreach (var end in list.FindAll(x => x == delimiter).Select(splitter => list.IndexOf(splitter, start)))
{
yield return list.GetRange(start, end - start);
start = end + 1;
}
if (start <= list.Count)
{
yield return list.GetRange(start, list.Count - start);
}
}
Upvotes: 0
Reputation: 100545
No, there is no special existing method in the framework to split sequence.
You code is reasonable.
Routes to improve/change:
yield return
instead of adding to output
to gain some lazy evaluation. Aggregate
if you want to show off single statement code...Upvotes: 2
Reputation: 35363
No built-in equivalent, but a lazy-evaluated one would be
IEnumerable<IEnumerable<T>> Split<T>(IEnumerable<T> list, T divider)
{
var temp = new List<T>();
foreach (var item in list)
{
if (!item.Equals(divider))
{
temp.Add(item);
}
else
{
yield return temp;
temp = new List<T>();
}
}
if(temp.Count>0) yield return temp;
}
Upvotes: 8