6using System.Collections;
7using System.Collections.Generic;
8using System.Diagnostics;
9using System.Globalization;
26 Func<int, int, Exception> errorSelector)
28 ICollection<TSource> collection = source as ICollection<TSource>;
30 if (collection !=
null)
32 if (collection.Count != count)
34 throw errorSelector(collection.Count.CompareTo(count), count);
40 return ExpectingCountYieldingImpl(source, count, errorSelector);
45 Func<int, int, Exception> errorSelector)
49 foreach (TSource element
in source)
53 if (iterations > count)
55 throw errorSelector(1, count);
61 if (iterations != count)
63 throw errorSelector(-1, count);
72 this IEnumerable<TFirst> first,
73 IEnumerable<TSecond> second,
74 Func<TFirst, TSecond, TResult> resultSelector)
78 throw new ArgumentNullException(nameof(first));
83 throw new ArgumentNullException(nameof(second));
86 if (resultSelector ==
null)
88 throw new ArgumentNullException(nameof(resultSelector));
91 return from element1 in first
92 from element2 in second
93 select resultSelector(element1, element2);
99 public static IEnumerable<TSource>
Prepend<TSource>(
this IEnumerable<TSource> source, TSource value)
103 throw new ArgumentNullException(nameof(source));
113 public static IEnumerable<T>
Concat<T>(
this T head, IEnumerable<T> tail)
117 throw new ArgumentNullException(nameof(tail));
120 return tail.Prepend(head);
126 public static IEnumerable<T>
Concat<T>(
this IEnumerable<T> head, T tail)
130 throw new ArgumentNullException(nameof(head));
140 public static IEnumerable<T>
Exclude<T>(
this IEnumerable<T> sequence,
int startIndex,
int count)
142 if (sequence ==
null)
144 throw new ArgumentNullException(nameof(sequence));
149 throw new ArgumentOutOfRangeException(nameof(startIndex));
154 throw new ArgumentOutOfRangeException(nameof(count));
157 return ExcludeImpl(sequence, startIndex, count);
160 private static IEnumerable<T>
ExcludeImpl<T>(IEnumerable<T> sequence,
int startIndex,
int count)
163 int endIndex = startIndex + count;
165 using (IEnumerator<T> iter = sequence.GetEnumerator())
168 while (iter.MoveNext() && ++index < startIndex)
170 yield
return iter.Current;
174 while (++index < endIndex && iter.MoveNext()) { }
177 while (iter.MoveNext())
179 yield
return iter.Current;
189 public static IEnumerable<KeyValuePair<int, TSource>>
Index<TSource>(
this IEnumerable<TSource> source)
191 return source.Index(0);
200 this IEnumerable<TSource> source,
203 return source.Select((element, index) =>
new KeyValuePair<int, TSource>(startIndex + index, element));
210 public static TResult
Fold<T, TResult>(
this IEnumerable<T> source, Func<T, TResult> folder)
212 return FoldImpl(source, 1, folder,
null,
null,
null);
219 public static TResult
Fold<T, TResult>(
this IEnumerable<T> source, Func<T, T, TResult> folder)
221 return FoldImpl(source, 2,
null, folder,
null,
null);
228 public static TResult
Fold<T, TResult>(
this IEnumerable<T> source, Func<T, T, T, TResult> folder)
230 return FoldImpl(source, 3,
null,
null, folder,
null);
237 public static TResult
Fold<T, TResult>(
this IEnumerable<T> source, Func<T, T, T, T, TResult> folder)
239 return FoldImpl(source, 4,
null,
null,
null, folder);
244 Func<T, TResult> folder1,
245 Func<T, T, TResult> folder2,
246 Func<T, T, T, TResult> folder3,
247 Func<T, T, T, T, TResult> folder4)
251 throw new ArgumentNullException(nameof(source));
254 if ((count == 1 && folder1 ==
null) ||
255 (count == 2 && folder2 ==
null) ||
256 (count == 3 && folder3 ==
null) ||
257 (count == 4 && folder4 ==
null))
260 throw new ArgumentNullException(
"folder");
263 T[] elements =
new T[count];
265 foreach (KeyValuePair<int, T> e
in AssertCountImpl(source.Index(),
270 elements[e.Key] = e.Value;
276 return folder1(elements[0]);
278 return folder2(elements[0], elements[1]);
280 return folder3(elements[0], elements[1], elements[2]);
282 return folder4(elements[0], elements[1], elements[2], elements[3]);
284 throw new NotSupportedException();
290 string message = cmp < 0
291 ?
"Sequence contains too few elements when exactly {0} {1} expected"
292 :
"Sequence contains too many elements when exactly {0} {1} expected";
294 return new Exception(
string.Format(message, count.ToString(
"N0"), count == 1 ?
"was" :
"were"));
300 public static void ForEach<T>(
this IEnumerable<T> source, Action<T> action)
304 throw new ArgumentNullException(nameof(source));
309 throw new ArgumentNullException(nameof(action));
312 foreach (T element
in source)
325 Func<TSource, TSource, TResult> resultSelector)
329 throw new ArgumentNullException(nameof(source));
332 if (resultSelector ==
null)
334 throw new ArgumentNullException(nameof(resultSelector));
337 return PairwiseImpl(source, resultSelector);
341 this IEnumerable<TSource> source,
342 Func<TSource, TSource, TResult> resultSelector)
344 Debug.Assert(source !=
null);
345 Debug.Assert(resultSelector !=
null);
347 using (IEnumerator<TSource> e = source.GetEnumerator())
354 TSource previous = e.Current;
358 yield
return resultSelector(previous, e.Current);
359 previous = e.Current;
370 return ToDelimitedString(source,
null);
381 throw new ArgumentNullException(nameof(source));
384 return ToDelimitedStringImpl(source, delimiter, (sb, e) => sb.Append(e));
389 Func<StringBuilder, T, StringBuilder> append)
391 Debug.Assert(source !=
null);
392 Debug.Assert(append !=
null);
394 delimiter = delimiter ?? CultureInfo.CurrentCulture.TextInfo.ListSeparator;
395 StringBuilder sb =
new StringBuilder();
398 foreach (T value
in source)
402 sb.Append(delimiter);
408 return sb.ToString();
414 public static IEnumerable<T>
Tail<T>(
this IEnumerable<T> source)
416 using (IEnumerator<T> e = source.GetEnumerator())
422 yield
return e.Current;
427 throw new ArgumentException(
"Source sequence cannot be empty", nameof(source));
437 using (IEnumerator<T> e = source.GetEnumerator())
443 yield
return e.Current;
452 public static IEnumerable<T>
Memoize<T>(
this IEnumerable<T> source)
454 return source.GetType()
480#if CSX_REM_CRYPTORAND
481 int index =
new Random().Next(source.Count() - 1);
483 var index =
new CryptoRandom().Next(source.Count() - 1);
485 return source.ElementAt(index);
491 public static IEnumerable<T>
Intersperse<T>(
this IEnumerable<T> source, T element)
495 throw new ArgumentNullException(nameof(element));
498 int count = source.Count();
499 int last = count - 1;
501 for (
int i = 0; i < count; i++)
503 yield
return source.ElementAt(i);
507 yield
return element;
515 public static IEnumerable<T>
FlattenOnce<T>(
this IEnumerable<IEnumerable<T>> source)
517 foreach (IEnumerable<T> element
in source)
519 foreach (T subelement
in element)
521 yield
return subelement;
530 public static IEnumerable<string>
FlattenOnce(
this IEnumerable<string> source)
532 foreach (
string element
in source)
534 string[] parts = element.Split();
536 foreach (
string part
in parts)
543#region Nested type: MaterializedEnumerable
547 private readonly ICollection<T>
inner;
551 inner = enumerable as ICollection<T> ?? enumerable.ToArray();
554#region IEnumerable<T> Members
558 return inner.GetEnumerator();
561 IEnumerator IEnumerable.GetEnumerator()
571#if !CSX_REM_MAYBE_FUNC
577 using (IEnumerator<T> e = source.GetEnumerator())
580 ?
Maybe.Just(e.Current)
581 :
Maybe.Nothing<T>();
590 using (IEnumerator<T> e = source.GetEnumerator())
594 :
Maybe.Nothing<IEnumerable<T>>();
System.Linq.Enumerable LinqEnumerable
IEnumerator< T > GetEnumerator()
readonly ICollection< T > inner
MaterializedEnumerable(IEnumerable< T > enumerable)
static IEnumerable< T > Concat< T >(this T head, IEnumerable< T > tail)
Returns a sequence consisting of the head element and the given tail elements.
static string ToDelimitedStringImpl< T >(IEnumerable< T > source, string delimiter, Func< StringBuilder, T, StringBuilder > append)
static T Choice< T >(this IEnumerable< T > source)
Selects a random element.
static Maybe< IEnumerable< T > > ToMaybe< T >(this IEnumerable< T > source)
Turns an empty sequence to Nothing, otherwise Just(sequence).
static Exception OnFolderSourceSizeError(int cmp, int count)
static IEnumerable< T > Memoize< T >(this IEnumerable< T > source)
Captures current state of a sequence.
static IEnumerable< KeyValuePair< int, TSource > > Index< TSource >(this IEnumerable< TSource > source)
Returns a sequence of KeyValuePair<TKey,TValue> where the key is the zero-based index of the value in...
static string ToDelimitedString< TSource >(this IEnumerable< TSource > source)
Creates a delimited string from a sequence of values. The delimiter used depends on the current cultu...
static TResult Fold< T, TResult >(this IEnumerable< T > source, Func< T, TResult > folder)
Returns the result of applying a function to a sequence of 1 element.
static IEnumerable< TSource > ExpectingCountYieldingImpl< TSource >(IEnumerable< TSource > source, int count, Func< int, int, Exception > errorSelector)
static IEnumerable< T > FlattenOnce< T >(this IEnumerable< IEnumerable< T > > source)
Flattens a sequence by one level.
static IEnumerable< T > Tail< T >(this IEnumerable< T > source)
Return everything except first element and throws exception if empty.
static TResult FoldImpl< T, TResult >(IEnumerable< T > source, int count, Func< T, TResult > folder1, Func< T, T, TResult > folder2, Func< T, T, T, TResult > folder3, Func< T, T, T, T, TResult > folder4)
static IEnumerable< T > Intersperse< T >(this IEnumerable< T > source, T element)
Takes an element and a sequence and ‘intersperses’ that element between its elements.
static readonly Func< int, int, Exception > OnFolderSourceSizeErrorSelector
static IEnumerable< string > FlattenOnce(this IEnumerable< string > source)
Reduces a sequence of strings to a sequence of parts, splitted by space, of each original string.
static IEnumerable< T > Materialize< T >(this IEnumerable< T > source)
Creates an immutable copy of a sequence.
static IEnumerable< TResult > Cartesian< TFirst, TSecond, TResult >(this IEnumerable< TFirst > first, IEnumerable< TSecond > second, Func< TFirst, TSecond, TResult > resultSelector)
Returns the Cartesian product of two sequences by combining each element of the first set with each i...
static Maybe< T > TryHead< T >(this IEnumerable< T > source)
Safe function that returns Just(first element) or None.
static IEnumerable< TSource > AssertCountImpl< TSource >(IEnumerable< TSource > source, int count, Func< int, int, Exception > errorSelector)
static IEnumerable< T > Exclude< T >(this IEnumerable< T > sequence, int startIndex, int count)
Excludes count elements from a sequence starting at a given index.
static void ForEach< T >(this IEnumerable< T > source, Action< T > action)
Immediately executes the given action on each element in the source sequence.
static IEnumerable< T > TailNoFail< T >(this IEnumerable< T > source)
Return everything except first element without throwing exception if empty.
static IEnumerable< TResult > PairwiseImpl< TSource, TResult >(this IEnumerable< TSource > source, Func< TSource, TSource, TResult > resultSelector)
static IEnumerable< TSource > Prepend< TSource >(this IEnumerable< TSource > source, TSource value)
Prepends a single value to a sequence.
static IEnumerable< T > ExcludeImpl< T >(IEnumerable< T > sequence, int startIndex, int count)
static IEnumerable< TResult > Pairwise< TSource, TResult >(this IEnumerable< TSource > source, Func< TSource, TSource, TResult > resultSelector)
Returns a sequence resulting from applying a function to each element in the source sequence and its ...
The Maybe type models an optional value. A value of type Maybe a either contains a value of type a (r...