Tanoda
QueryCollapseExtensions.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using System;
10using System.Collections.Generic;
11
12namespace Leap.Unity.Query {
13
14 public static class QueryCollapseExtensions {
15
19 public static bool All<T>(this Query<T> query, Func<T, bool> predicate) {
20 using (var slice = query.Deconstruct()) {
21
22 for (int i = 0; i < slice.Count; i++) {
23 if (!predicate(slice[i])) {
24 return false;
25 }
26 }
27 return true;
28
29 }
30 }
31
36 public static bool AllEqual<T>(this Query<T> query) {
37 using (var slice = query.Deconstruct()) {
38 if (slice.Count <= 1) {
39 return true;
40 }
41
42 var comparer = EqualityComparer<T>.Default;
43
44 var first = slice[0];
45 for (int i = 1; i < slice.Count; i++) {
46 if (!comparer.Equals(first, slice[i])) {
47 return false;
48 }
49 }
50
51 return true;
52 }
53 }
54
58 public static bool Any<T>(this Query<T> query) {
59 return query.Count() > 0;
60 }
61
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])) {
69 return true;
70 }
71 }
72
73 return false;
74 }
75 }
76
80 public static float Average(this Query<float> query) {
81 using (var slice = query.Deconstruct()) {
82 float sum = 0;
83 for (int i = 0; i < slice.Count; i++) {
84 sum += slice[i];
85 }
86 return sum / slice.Count;
87 }
88 }
89
93 public static double Average(this Query<double> query) {
94 using (var slice = query.Deconstruct()) {
95 double sum = 0;
96 for (int i = 0; i < slice.Count; i++) {
97 sum += slice[i];
98 }
99 return sum / slice.Count;
100 }
101 }
102
106 public static bool Contains<T>(this Query<T> query, T item) {
107 T[] array;
108 int count;
109 query.Deconstruct(out array, out count);
110
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);
115 return true;
116 }
117 }
118
119 ArrayPool<T>.Recycle(array);
120 return false;
121 }
122
126 public static int Count<T>(this Query<T> query) {
127 using (var slice = query.Deconstruct()) {
128 return slice.Count;
129 }
130 }
131
135 public static int Count<T>(this Query<T> query, Func<T, bool> predicate) {
136 return query.Where(predicate).Count();
137 }
138
142 public static int CountUnique<T>(this Query<T> query) {
143 var slice = query.Deconstruct();
144 var set = Pool<HashSet<T>>.Spawn();
145 try {
146
147 for (int i = 0; i < slice.Count; i++) {
148 set.Add(slice[i]);
149 }
150 return set.Count;
151
152 } finally {
153 slice.Dispose();
154 set.Clear();
155 Pool<HashSet<T>>.Recycle(set);
156 }
157 }
158
163 public static int CountUnique<T, K>(this Query<T> query, Func<T, K> selector) {
164 return query.Select(selector).CountUnique();
165 }
166
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);
175 }
176 return slice[index];
177 }
178 }
179
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) {
187 return default(T);
188 }
189 return slice[index];
190 }
191 }
192
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.");
201 }
202 return slice[0];
203 }
204 }
205
210 public static T First<T>(this Query<T> query, Func<T, bool> predicate) {
211 return query.Where(predicate).First();
212 }
213
218 public static T FirstOrDefault<T>(this Query<T> query) {
219 using (var slice = query.Deconstruct()) {
220 if (slice.Count == 0) {
221 return default(T);
222 }
223 return slice[0];
224 }
225 }
226
231 public static T FirstOrDefault<T>(this Query<T> query, Func<T, bool> predicate) {
232 return query.Where(predicate).FirstOrDefault();
233 }
234
239 public static Maybe<T> FirstOrNone<T>(this Query<T> query) {
240 using (var slice = query.Deconstruct()) {
241 if (slice.Count == 0) {
242 return Maybe.None;
243 }
244 return Maybe.Some(slice[0]);
245 }
246 }
247
252 public static Maybe<T> FirstOrNone<T>(this Query<T> query, Func<T, bool> predicate) {
253 return query.Where(predicate).FirstOrNone();
254 }
255
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.");
270 }
271
272 var result = slice[0];
273 for (int i = 1; i < slice.Count; i++) {
274 result = foldFunc(result, slice[i]);
275 }
276
277 return result;
278 }
279 }
280
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])) {
290 return i;
291 }
292 }
293
294 return -1;
295 }
296 }
297
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])) {
306 return i;
307 }
308 }
309 return -1;
310 }
311 }
312
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.");
320 } else {
321 return slice[slice.Count - 1];
322 }
323 }
324 }
325
330 public static T Last<T>(this Query<T> query, Func<T, bool> predicate) {
331 return query.Where(predicate).Last();
332 }
333
337 public static T LastOrDefault<T>(this Query<T> query) {
338 using (var slice = query.Deconstruct()) {
339 if (slice.Count == 0) {
340 return default(T);
341 } else {
342 return slice[slice.Count - 1];
343 }
344 }
345 }
346
351 public static T LastOrDefault<T>(this Query<T> query, Func<T, bool> predicate) {
352 return query.Where(predicate).LastOrDefault();
353 }
354
359 public static Maybe<T> LastOrNone<T>(this Query<T> query) {
360 using (var slice = query.Deconstruct()) {
361 if (slice.Count == 0) {
362 return Maybe.None;
363 } else {
364 return Maybe.Some(slice[slice.Count - 1]);
365 }
366 }
367 }
368
373 public static Maybe<T> LastOrNone<T>(this Query<T> query, Func<T, bool> predicate) {
374 return query.Where(predicate).LastOrNone();
375 }
376
380 public static T Max<T>(this Query<T> query) where T : IComparable<T> {
381 return query.Fold(FoldDelegate<T>.max);
382 }
383
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();
389 }
390
394 public static T Min<T>(this Query<T> query) where T : IComparable<T> {
395 return query.Fold(FoldDelegate<T>.min);
396 }
397
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();
403 }
404
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.");
413 } else {
414 return slice[0];
415 }
416 }
417 }
418
423 public static T Single<T>(this Query<T> query, Func<T, bool> predicate) {
424 return query.Where(predicate).Single();
425 }
426
431 public static T SingleOrDefault<T>(this Query<T> query) {
432 using (var slice = query.Deconstruct()) {
433 if (slice.Count != 1) {
434 return default(T);
435 } else {
436 return slice[0];
437 }
438 }
439 }
440
445 public static T SingleOrDefault<T>(this Query<T> query, Func<T, bool> predicate) {
446 return query.Where(predicate).SingleOrDefault();
447 }
448
453 public static Maybe<T> SingleOrNone<T>(this Query<T> query) {
454 using (var slice = query.Deconstruct()) {
455 if (slice.Count != 1) {
456 return Maybe.None;
457 } else {
458 return Maybe.Some(slice[0]);
459 }
460 }
461 }
462
467 public static Maybe<T> SingleOrNone<T>(this Query<T> query, Func<T, bool> predicate) {
468 return query.Where(predicate).SingleOrNone();
469 }
470
474 public static int Sum(this Query<int> query) {
475 return query.Fold((a, b) => a + b);
476 }
477
481 public static float Sum(this Query<float> query) {
482 return query.Fold((a, b) => a + b);
483 }
484
488 public static double Sum(this Query<double> query) {
489 return query.Fold((a, b) => a + b);
490 }
491
497 public static T UniformOrDefault<T>(this Query<T> query) {
498 return query.UniformOrNone().valueOrDefault;
499 }
500
506 public static Maybe<T> UniformOrNone<T>(this Query<T> query) {
507 using (var slice = query.Deconstruct()) {
508 if (slice.Count == 0) {
509 return Maybe.None;
510 }
511
512 var array = slice;
513 T reference = array[0];
514
515 var comparer = EqualityComparer<T>.Default;
516 for (int i = 1; i < slice.Count; i++) {
517 if (!comparer.Equals(reference, slice[i])) {
518 return Maybe.None;
519 }
520 }
521
522 return Maybe.Some(reference);
523 }
524 }
525
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);
533 return result;
534 }
535 }
536
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);
544 }
545 }
546
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]);
555 }
556 return result;
557 }
558 }
559
563 public static void FillList<T>(this Query<T> query, List<T> list) {
564 list.Clear();
565 query.AppendList(list);
566 }
567
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++) {
574 list.Add(slice[i]);
575 }
576 }
577 }
578
582 public static HashSet<T> ToHashSet<T>(this Query<T> query) {
583 HashSet<T> set = new HashSet<T>();
584 query.AppendHashSet(set);
585 return set;
586 }
587
591 public static void FillHashSet<T>(this Query<T> query, HashSet<T> set) {
592 set.Clear();
593 query.AppendHashSet(set);
594 }
595
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++) {
602 set.Add(slice[i]);
603 }
604 }
605 }
606
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>();
613
614 for (int i = 0; i < slice.Count; i++) {
615 dictionary[keySelector(slice[i])] = valueSelector(slice[i]);
616 }
617
618 return dictionary;
619 }
620 }
621
626 public static Dictionary<T, V> ToDictionary<T, V>(this Query<T> query, Func<T, V> valueSelector) {
627 return query.ToDictionary(t => t, valueSelector);
628 }
629
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;
633 }
634 }
635}