You have a relationship between the individual elements of your collection, in particular for each element that you want to know, "was the previous element equal to zero?". As soon as your request depends on the previous element (or, in general, as soon as your request depends on other elements of the same sequence), you should achieve for Aggregate(or in more general functional terms of programming fold). This is due to the fact that Aggregate, unlike other LINQ statements, it allows you to transfer the state with you from one iteration to the next.
, , LINQ.
var splitByZero = values.Aggregate(new List<List<int>>{new List<int>()},
(list, value) => {
list.Last().Add(value);
if (value == 0) list.Add(new List<int>());
return list;
});
, .
values.Aggregate(new List<List<int>>{new List<int>()},
, , . List<List<int>>, .
(list, value) => {...}
, - ( Func<List<List<int>>, int, List<List<int>>), , : List<List<int>> .
list.Last().Add(value);
List<int>, Last() ( - ).
if (value == 0) list.Add(new List<int>());
- Last() .
return list;
, , .
SplitOn :
public static IEnumerable<IEnumerable<T>> SplitOn<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
return source.Aggregate(new List<List<T>> {new List<T>()},
(list, value) =>
{
list.Last().Add(value);
if (predicate(value)) list.Add(new List<T>());
return list;
});
}
, IEnumerable List, - , Enumerables, - , ( ):
public static IEnumerable<IEnumerable<T>> SplitOn<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
return source.Aggregate(Enumerable.Repeat(Enumerable.Empty<T>(), 1),
(list, value) =>
{
list.Last().Concat(Enumerable.Repeat(value, 1));
return predicate(value) ? list.Concat(Enumerable.Repeat(Enumerable.Empty<T>(), 1)) : list;
});
}
Haskell splitOn, , . ( ).