10using System.Collections.Generic;
14 public static class QueryCollapseExtensions {
19 public static bool All<T>(
this Query<T> query, Func<T, bool> predicate) {
20 using (var slice = query.Deconstruct()) {
22 for (
int i = 0; i < slice.Count; i++) {
23 if (!predicate(slice[i])) {
36 public static bool AllEqual<T>(
this Query<T> query) {
37 using (var slice = query.Deconstruct()) {
38 if (slice.Count <= 1) {
42 var comparer = EqualityComparer<T>.Default;
45 for (
int i = 1; i < slice.Count; i++) {
46 if (!comparer.Equals(first, slice[i])) {
58 public static bool Any<T>(
this Query<T> query) {
59 return query.Count() > 0;
65 public static bool Any<T>(
this Query<T> query, Func<T, bool> predicate) {
66 using (var slice = query.Deconstruct()) {
67 for (
int i = 0; i < slice.Count; i++) {
68 if (predicate(slice[i])) {
80 public static float Average(
this Query<float> query) {
81 using (var slice = query.Deconstruct()) {
83 for (
int i = 0; i < slice.Count; i++) {
86 return sum / slice.Count;
93 public static double Average(
this Query<double> query) {
94 using (var slice = query.Deconstruct()) {
96 for (
int i = 0; i < slice.Count; i++) {
99 return sum / slice.Count;
106 public static bool Contains<T>(
this Query<T> query, T item) {
109 query.Deconstruct(out array, out count);
111 var comparer = EqualityComparer<T>.Default;
112 for (
int i = 0; i < count; i++) {
113 if (comparer.Equals(item, array[i])) {
114 ArrayPool<T>.Recycle(array);
119 ArrayPool<T>.Recycle(array);
126 public static int Count<T>(
this Query<T> query) {
127 using (var slice = query.Deconstruct()) {
135 public static int Count<T>(
this Query<T> query, Func<T, bool> predicate) {
136 return query.Where(predicate).Count();
142 public static int CountUnique<T>(
this Query<T> query) {
143 var slice = query.Deconstruct();
144 var
set = Pool<HashSet<T>>.Spawn();
147 for (
int i = 0; i < slice.Count; i++) {
155 Pool<HashSet<T>>.Recycle(
set);
163 public static int CountUnique<T, K>(
this Query<T> query, Func<T, K> selector) {
164 return query.Select(selector).CountUnique();
171 public static T ElementAt<T>(
this Query<T> query,
int index) {
172 using (var slice = query.Deconstruct()) {
173 if (index < 0 || index >= slice.Count) {
174 throw new IndexOutOfRangeException(
"The index " + index +
" was out of range. Query only has length of " + slice.Count);
184 public static T ElementAtOrDefault<T>(
this Query<T> query,
int index) {
185 using (var slice = query.Deconstruct()) {
186 if (index < 0 || index >= slice.Count) {
197 public static T First<T>(
this Query<T> query) {
198 using (var slice = query.Deconstruct()) {
199 if (slice.Count == 0) {
200 throw new InvalidOperationException(
"The source Query was empty.");
210 public static T First<T>(
this Query<T> query, Func<T, bool> predicate) {
211 return query.Where(predicate).First();
218 public static T FirstOrDefault<T>(
this Query<T> query) {
219 using (var slice = query.Deconstruct()) {
220 if (slice.Count == 0) {
231 public static T FirstOrDefault<T>(
this Query<T> query, Func<T, bool> predicate) {
232 return query.Where(predicate).FirstOrDefault();
239 public static Maybe<T> FirstOrNone<T>(
this Query<T> query) {
240 using (var slice = query.Deconstruct()) {
241 if (slice.Count == 0) {
244 return Maybe.Some(slice[0]);
252 public static Maybe<T> FirstOrNone<T>(
this Query<T> query, Func<T, bool> predicate) {
253 return query.Where(predicate).FirstOrNone();
266 public static T Fold<T>(
this Query<T> query, Func<T, T, T> foldFunc) {
267 using (var slice = query.Deconstruct()) {
268 if (slice.Count == 0) {
269 throw new InvalidOperationException(
"The source Query was empty.");
272 var result = slice[0];
273 for (
int i = 1; i < slice.Count; i++) {
274 result = foldFunc(result, slice[i]);
285 public static int IndexOf<T>(
this Query<T> query, T t) {
286 using (var slice = query.Deconstruct()) {
287 var comparer = EqualityComparer<T>.Default;
288 for (
int i = 0; i < slice.Count; i++) {
289 if (comparer.Equals(t, slice[i])) {
302 public static int IndexOf<T>(
this Query<T> query, Func<T, bool> predicate) {
303 using (var slice = query.Deconstruct()) {
304 for (
int i = 0; i < slice.Count; i++) {
305 if (predicate(slice[i])) {
316 public static T Last<T>(
this Query<T> query) {
317 using (var slice = query.Deconstruct()) {
318 if (slice.Count == 0) {
319 throw new InvalidOperationException(
"The source Query was empty.");
321 return slice[slice.Count - 1];
330 public static T Last<T>(
this Query<T> query, Func<T, bool> predicate) {
331 return query.Where(predicate).Last();
337 public static T LastOrDefault<T>(
this Query<T> query) {
338 using (var slice = query.Deconstruct()) {
339 if (slice.Count == 0) {
342 return slice[slice.Count - 1];
351 public static T LastOrDefault<T>(
this Query<T> query, Func<T, bool> predicate) {
352 return query.Where(predicate).LastOrDefault();
359 public static Maybe<T> LastOrNone<T>(
this Query<T> query) {
360 using (var slice = query.Deconstruct()) {
361 if (slice.Count == 0) {
364 return Maybe.Some(slice[slice.Count - 1]);
373 public static Maybe<T> LastOrNone<T>(
this Query<T> query, Func<T, bool> predicate) {
374 return query.Where(predicate).LastOrNone();
380 public static T Max<T>(
this Query<T> query) where T : IComparable<T> {
381 return query.Fold(FoldDelegate<T>.max);
387 public static K Max<T, K>(
this Query<T> query, Func<T, K> selector) where K : IComparable<K> {
388 return query.Select(selector).Max();
394 public static T Min<T>(
this Query<T> query) where T : IComparable<T> {
395 return query.Fold(FoldDelegate<T>.min);
401 public static K Min<T, K>(
this Query<T> query, Func<T, K> selector) where K : IComparable<K> {
402 return query.Select(selector).Min();
409 public static T Single<T>(
this Query<T> query) {
410 using (var slice = query.Deconstruct()) {
411 if (slice.Count != 1) {
412 throw new InvalidOperationException(
"The Query had a count of " + slice.Count +
" instead of a count of 1.");
423 public static T Single<T>(
this Query<T> query, Func<T, bool> predicate) {
424 return query.Where(predicate).Single();
431 public static T SingleOrDefault<T>(
this Query<T> query) {
432 using (var slice = query.Deconstruct()) {
433 if (slice.Count != 1) {
445 public static T SingleOrDefault<T>(
this Query<T> query, Func<T, bool> predicate) {
446 return query.Where(predicate).SingleOrDefault();
453 public static Maybe<T> SingleOrNone<T>(
this Query<T> query) {
454 using (var slice = query.Deconstruct()) {
455 if (slice.Count != 1) {
458 return Maybe.Some(slice[0]);
467 public static Maybe<T> SingleOrNone<T>(
this Query<T> query, Func<T, bool> predicate) {
468 return query.Where(predicate).SingleOrNone();
474 public static int Sum(
this Query<int> query) {
475 return query.Fold((a, b) => a + b);
481 public static float Sum(
this Query<float> query) {
482 return query.Fold((a, b) => a + b);
488 public static double Sum(
this Query<double> query) {
489 return query.Fold((a, b) => a + b);
497 public static T UniformOrDefault<T>(
this Query<T> query) {
498 return query.UniformOrNone().valueOrDefault;
506 public static Maybe<T> UniformOrNone<T>(
this Query<T> query) {
507 using (var slice = query.Deconstruct()) {
508 if (slice.Count == 0) {
513 T reference = array[0];
515 var comparer = EqualityComparer<T>.Default;
516 for (
int i = 1; i < slice.Count; i++) {
517 if (!comparer.Equals(reference, slice[i])) {
522 return Maybe.Some(reference);
529 public static T[] ToArray<T>(
this Query<T> query) {
530 using (var slice = query.Deconstruct()) {
531 T[] result =
new T[slice.Count];
532 Array.Copy(slice.BackingArray, result, slice.Count);
541 public static void FillArray<T>(
this Query<T> query, T[] array,
int offset = 0) {
542 using (var slice = query.Deconstruct()) {
543 Array.Copy(slice.BackingArray, 0, array, offset, slice.Count);
550 public static List<T> ToList<T>(
this Query<T> query) {
551 using (var slice = query.Deconstruct()) {
552 List<T> result =
new List<T>(slice.Count);
553 for (
int i = 0; i < slice.Count; i++) {
554 result.Add(slice[i]);
563 public static void FillList<T>(
this Query<T> query, List<T> list) {
565 query.AppendList(list);
571 public static void AppendList<T>(
this Query<T> query, List<T> list) {
572 using (var slice = query.Deconstruct()) {
573 for (
int i = 0; i < slice.Count; i++) {
582 public static HashSet<T> ToHashSet<T>(
this Query<T> query) {
583 HashSet<T>
set =
new HashSet<T>();
584 query.AppendHashSet(
set);
591 public static void FillHashSet<T>(
this Query<T> query, HashSet<T>
set) {
593 query.AppendHashSet(
set);
599 public static void AppendHashSet<T>(
this Query<T> query, HashSet<T>
set) {
600 using (var slice = query.Deconstruct()) {
601 for (
int i = 0; i < slice.Count; i++) {
610 public static Dictionary<K, V> ToDictionary<T, K, V>(
this Query<T> query, Func<T, K> keySelector, Func<T, V> valueSelector) {
611 using (var slice = query.Deconstruct()) {
612 Dictionary<K, V> dictionary =
new Dictionary<K, V>();
614 for (
int i = 0; i < slice.Count; i++) {
615 dictionary[keySelector(slice[i])] = valueSelector(slice[i]);
626 public static Dictionary<T, V> ToDictionary<T, V>(
this Query<T> query, Func<T, V> valueSelector) {
627 return query.ToDictionary(t => t, valueSelector);
630 private static class FoldDelegate<T> where T : IComparable<T> {
631 public readonly
static Func<T, T, T> max = (a, b) => a.CompareTo(b) > 0 ? a : b;
632 public readonly
static Func<T, T, T> min = (a, b) => a.CompareTo(b) < 0 ? a : b;