linqx 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/linq.js ADDED
@@ -0,0 +1,3085 @@
1
+ /*--------------------------------------------------------------------------
2
+ * linq.js - LINQ for JavaScript
3
+ * licensed under MIT License
4
+ *------------------------------------------------------------------------*/
5
+
6
+ var Functions = {
7
+ Identity: function (x) { return x; },
8
+ True: function () { return true; },
9
+ Blank: function () { }
10
+ };
11
+
12
+ var Types = {
13
+ Boolean: typeof true,
14
+ Number: typeof 0,
15
+ String: typeof "",
16
+ Object: typeof {},
17
+ Undefined: typeof undefined,
18
+ Function: typeof function () { }
19
+ };
20
+
21
+ var funcCache = { "": Functions.Identity };
22
+
23
+ var Utils = {
24
+ createLambda: function (expression) {
25
+ if (expression == null) return Functions.Identity;
26
+ if (typeof expression === Types.String) {
27
+ // get from cache
28
+ let f = funcCache[expression];
29
+ if (f != null) {
30
+ return f;
31
+ }
32
+
33
+ if (expression.indexOf("=>") === -1) {
34
+ const regexp = new RegExp("[$]+", "g");
35
+
36
+ let maxLength = 0;
37
+ let match;
38
+ while ((match = regexp.exec(expression)) != null) {
39
+ if (match[0].length > maxLength) {
40
+ maxLength = match[0].length;
41
+ }
42
+ }
43
+
44
+ const argArray = [];
45
+ for (let i = 1; i <= maxLength; i++) {
46
+ let dollar = "";
47
+ for (let j = 0; j < i; j++) {
48
+ dollar += "$";
49
+ }
50
+ argArray.push(dollar);
51
+ }
52
+
53
+ const args = argArray.join(",");
54
+
55
+ f = new Function(args, "return " + expression);
56
+ funcCache[expression] = f;
57
+ return f;
58
+ }
59
+ else {
60
+ const expr = expression.match(/^[(\s]*([^()]*?)[)\s]*=>(.*)/);
61
+ f = new Function(expr[1], (expr[2].match(/\breturn\b/) ? expr[2] : "return " + expr[2]));
62
+ funcCache[expression] = f;
63
+ return f;
64
+ }
65
+ }
66
+ return expression;
67
+ },
68
+
69
+ defineProperty: function (target, methodName, value) {
70
+ Object.defineProperty(target, methodName, {
71
+ enumerable: false,
72
+ configurable: true,
73
+ writable: true,
74
+ value: value
75
+ })
76
+ },
77
+
78
+ compare: function (a, b) {
79
+ return (a === b) ? 0 : (a > b) ? 1 : -1;
80
+ },
81
+
82
+ dispose: function (obj) {
83
+ if (obj != null) obj.dispose();
84
+ },
85
+
86
+ hasNativeIteratorSupport: function () {
87
+ return typeof Symbol !== 'undefined' && typeof Symbol.iterator !== 'undefined';
88
+ }
89
+ };
90
+
91
+ var State = { Before: 0, Running: 1, After: 2 };
92
+
93
+ var IEnumerator = function (initialize, tryGetNext, dispose) {
94
+ var yielder = new Yielder();
95
+ var state = State.Before;
96
+
97
+ this.current = yielder.current;
98
+
99
+ this.moveNext = function () {
100
+ try {
101
+ switch (state) {
102
+ case State.Before:
103
+ state = State.Running;
104
+ initialize();
105
+ // fall through
106
+
107
+ case State.Running:
108
+ if (tryGetNext.apply(yielder)) {
109
+ return true;
110
+ }
111
+ else {
112
+ this.dispose();
113
+ return false;
114
+ }
115
+ // fall through
116
+
117
+ case State.After:
118
+ return false;
119
+ }
120
+ }
121
+ catch (e) {
122
+ this.dispose();
123
+ throw e;
124
+ }
125
+ };
126
+
127
+ this.dispose = function () {
128
+ if (state != State.Running) return;
129
+
130
+ try {
131
+ dispose();
132
+ }
133
+ finally {
134
+ state = State.After;
135
+ }
136
+ };
137
+ };
138
+
139
+ // tryGetNext yielder
140
+ var Yielder = function () {
141
+ var current = null;
142
+ this.current = function () { return current; };
143
+ this.yieldReturn = function (value) {
144
+ current = value;
145
+ return true;
146
+ };
147
+ this.yieldBreak = function () {
148
+ return false;
149
+ };
150
+ };
151
+
152
+ // Enumerable constuctor
153
+ var Enumerable = function (getEnumerator) {
154
+ this.getEnumerator = getEnumerator;
155
+ };
156
+
157
+ ///////////////////
158
+ // Utility Methods
159
+
160
+ Enumerable.Utils = {};
161
+
162
+ Enumerable.Utils.createLambda = function (expression) {
163
+ return Utils.createLambda(expression);
164
+ };
165
+
166
+ Enumerable.Utils.createEnumerable = function (getEnumerator) {
167
+ return new Enumerable(getEnumerator);
168
+ };
169
+
170
+ Enumerable.Utils.createEnumerator = function (initialize, tryGetNext, dispose) {
171
+ return new IEnumerator(initialize, tryGetNext, dispose);
172
+ };
173
+
174
+ Enumerable.Utils.extendTo = function (type) {
175
+ var typeProto = type.prototype;
176
+ var enumerableProto;
177
+
178
+ if (type === Array) {
179
+ enumerableProto = ArrayEnumerable.prototype;
180
+ Utils.defineProperty(typeProto, "getSource", function () {
181
+ return this;
182
+ });
183
+ }
184
+ else {
185
+ enumerableProto = Enumerable.prototype;
186
+ Utils.defineProperty(typeProto, "getEnumerator", function () {
187
+ return Enumerable.from(this).getEnumerator();
188
+ });
189
+ }
190
+
191
+ for (let methodName in enumerableProto) {
192
+ const func = enumerableProto[methodName];
193
+
194
+ // already extended
195
+ if (typeProto[methodName] == func) continue;
196
+
197
+ // already defined(example Array#reverse/join/forEach...)
198
+ if (typeProto[methodName] != null) {
199
+ methodName = methodName + "ByLinq";
200
+ if (typeProto[methodName] == func) continue; // recheck
201
+ }
202
+
203
+ if (func instanceof Function) {
204
+ Utils.defineProperty(typeProto, methodName, func);
205
+ }
206
+ }
207
+ };
208
+
209
+ Enumerable.Utils.recallFrom = function (type) {
210
+ var typeProto = type.prototype;
211
+ var enumerableProto;
212
+
213
+ if (type === Array) {
214
+ enumerableProto = ArrayEnumerable.prototype;
215
+ delete typeProto.getSource;
216
+ }
217
+ else {
218
+ enumerableProto = Enumerable.prototype;
219
+ delete typeProto.getEnumerator;
220
+ }
221
+
222
+ for (const methodName in enumerableProto) {
223
+ const func = enumerableProto[methodName];
224
+
225
+ if (typeProto[methodName + 'ByLinq']) {
226
+ delete typeProto[methodName + 'ByLinq'];
227
+ }
228
+ else if (typeProto[methodName] == func && func instanceof Function) {
229
+ delete typeProto[methodName];
230
+ }
231
+ }
232
+ };
233
+
234
+ //////////////
235
+ // Generators
236
+
237
+ Enumerable.choice = function () {
238
+ var args = arguments;
239
+
240
+ return new Enumerable(function () {
241
+ return new IEnumerator(
242
+ function () {
243
+ args = (args[0] instanceof Array) ? args[0]
244
+ : (args[0].getEnumerator != null) ? args[0].toArray()
245
+ : args;
246
+ },
247
+ function () {
248
+ return this.yieldReturn(args[Math.floor(Math.random() * args.length)]);
249
+ },
250
+ Functions.Blank);
251
+ });
252
+ };
253
+
254
+ Enumerable.cycle = function () {
255
+ var args = arguments;
256
+
257
+ return new Enumerable(function () {
258
+ var index = 0;
259
+ return new IEnumerator(
260
+ function () {
261
+ args = (args[0] instanceof Array) ? args[0]
262
+ : (args[0].getEnumerator != null) ? args[0].toArray()
263
+ : args;
264
+ },
265
+ function () {
266
+ if (index >= args.length) index = 0;
267
+ return this.yieldReturn(args[index++]);
268
+ },
269
+ Functions.Blank);
270
+ });
271
+ };
272
+
273
+ Enumerable.empty = function () {
274
+ return new Enumerable(function () {
275
+ return new IEnumerator(
276
+ Functions.Blank,
277
+ function () { return false; },
278
+ Functions.Blank);
279
+ });
280
+ };
281
+
282
+ Enumerable.from = function (obj) {
283
+ if (obj == null) {
284
+ return Enumerable.empty();
285
+ }
286
+ if (obj instanceof Enumerable) {
287
+ return obj;
288
+ }
289
+ if (typeof obj == Types.Number || typeof obj == Types.Boolean) {
290
+ return Enumerable.repeat(obj, 1);
291
+ }
292
+ if (typeof obj == Types.String) {
293
+ return new Enumerable(function () {
294
+ var index = 0;
295
+ return new IEnumerator(
296
+ Functions.Blank,
297
+ function () {
298
+ return (index < obj.length) ? this.yieldReturn(obj.charAt(index++)) : false;
299
+ },
300
+ Functions.Blank);
301
+ });
302
+ }
303
+ if (typeof obj == Types.Function && Object.keys(obj).length == 0) {
304
+ return new Enumerable(function () {
305
+ var orig;
306
+
307
+ return new IEnumerator(
308
+ function () {
309
+ orig = obj()[Symbol.iterator]();
310
+ },
311
+ function () {
312
+ var next = orig.next();
313
+ return (next.done ? false : (this.yieldReturn(next.value)));
314
+ },
315
+ Functions.Blank);
316
+ });
317
+ }
318
+
319
+ if (typeof obj != Types.Function) {
320
+ // array or array-like object
321
+ if (typeof obj.length == Types.Number) {
322
+ return new ArrayEnumerable(obj);
323
+ }
324
+
325
+ // iterable object
326
+ if (typeof Symbol !== 'undefined' && typeof obj[Symbol.iterator] !== 'undefined') {
327
+ let iterator;
328
+ return new Enumerable(function () {
329
+ return new IEnumerator(
330
+ function () { iterator = obj[Symbol.iterator]()},
331
+ function () {
332
+ var next = iterator.next();
333
+ return (next.done ? false : (this.yieldReturn(next.value)));
334
+ },
335
+ Functions.Blank);
336
+ });
337
+ }
338
+
339
+ // object conforming to the iterator protocol
340
+ if (typeof obj.next == Types.Function) {
341
+ return new Enumerable(function () {
342
+ return new IEnumerator(
343
+ Functions.Blank,
344
+ function () {
345
+ var next = obj.next();
346
+ return (next.done ? false : (this.yieldReturn(next.value)));
347
+ },
348
+ Functions.Blank);
349
+ });
350
+ }
351
+ }
352
+
353
+ // case function/object: create keyValuePair[]
354
+ return new Enumerable(function () {
355
+ var array = [];
356
+ var index = 0;
357
+
358
+ return new IEnumerator(
359
+ function () {
360
+ for (const key in obj) {
361
+ const value = obj[key];
362
+ if (!(value instanceof Function) && Object.prototype.hasOwnProperty.call(obj, key)) {
363
+ array.push({ key: key, value: value });
364
+ }
365
+ }
366
+ },
367
+ function () {
368
+ return (index < array.length)
369
+ ? this.yieldReturn(array[index++])
370
+ : false;
371
+ },
372
+ Functions.Blank);
373
+ });
374
+ },
375
+
376
+ Enumerable.make = function (element) {
377
+ return Enumerable.repeat(element, 1);
378
+ };
379
+
380
+ // Overload:function(input, pattern)
381
+ // Overload:function(input, pattern, flags)
382
+ Enumerable.matches = function (input, pattern, flags) {
383
+ if (flags == null) flags = "";
384
+
385
+ if (pattern instanceof RegExp) {
386
+ flags += (pattern.ignoreCase) ? "i" : "";
387
+ flags += (pattern.multiline) ? "m" : "";
388
+ pattern = pattern.source;
389
+ }
390
+ if (flags.indexOf("g") === -1) flags += "g";
391
+
392
+ return new Enumerable(function () {
393
+ var regex;
394
+ return new IEnumerator(
395
+ function () { regex = new RegExp(pattern, flags); },
396
+ function () {
397
+ var match = regex.exec(input);
398
+ return (match) ? this.yieldReturn(match) : false;
399
+ },
400
+ Functions.Blank);
401
+ });
402
+ };
403
+
404
+ // Overload:function(start, count)
405
+ // Overload:function(start, count, step)
406
+ Enumerable.range = function (start, count, step) {
407
+ if (step == null) step = 1;
408
+
409
+ return new Enumerable(function () {
410
+ var value;
411
+ var index = 0;
412
+
413
+ return new IEnumerator(
414
+ function () { value = start - step; },
415
+ function () {
416
+ return (index++ < count)
417
+ ? this.yieldReturn(value += step)
418
+ : this.yieldBreak();
419
+ },
420
+ Functions.Blank);
421
+ });
422
+ };
423
+
424
+ // Overload:function(start, count)
425
+ // Overload:function(start, count, step)
426
+ Enumerable.rangeDown = function (start, count, step) {
427
+ if (step == null) step = 1;
428
+
429
+ return new Enumerable(function () {
430
+ var value;
431
+ var index = 0;
432
+
433
+ return new IEnumerator(
434
+ function () { value = start + step; },
435
+ function () {
436
+ return (index++ < count)
437
+ ? this.yieldReturn(value -= step)
438
+ : this.yieldBreak();
439
+ },
440
+ Functions.Blank);
441
+ });
442
+ };
443
+
444
+ // Overload:function(start, to)
445
+ // Overload:function(start, to, step)
446
+ Enumerable.rangeTo = function (start, to, step) {
447
+ if (step == null) step = 1;
448
+
449
+ if (start < to) {
450
+ return new Enumerable(function () {
451
+ var value;
452
+
453
+ return new IEnumerator(
454
+ function () { value = start - step; },
455
+ function () {
456
+ var next = value += step;
457
+ return (next <= to)
458
+ ? this.yieldReturn(next)
459
+ : this.yieldBreak();
460
+ },
461
+ Functions.Blank);
462
+ });
463
+ }
464
+ else {
465
+ return new Enumerable(function () {
466
+ var value;
467
+
468
+ return new IEnumerator(
469
+ function () { value = start + step; },
470
+ function () {
471
+ var next = value -= step;
472
+ return (next >= to)
473
+ ? this.yieldReturn(next)
474
+ : this.yieldBreak();
475
+ },
476
+ Functions.Blank);
477
+ });
478
+ }
479
+ };
480
+
481
+ // Overload:function(element)
482
+ // Overload:function(element, count)
483
+ Enumerable.repeat = function (element, count) {
484
+ if (count != null)
485
+ return Enumerable.repeat(element).take(count);
486
+
487
+ return new Enumerable(function () {
488
+ return new IEnumerator(
489
+ Functions.Blank,
490
+ function () { return this.yieldReturn(element); },
491
+ Functions.Blank);
492
+ });
493
+ };
494
+
495
+ Enumerable.repeatWithFinalize = function (initializer, finalizer) {
496
+ initializer = Utils.createLambda(initializer);
497
+ finalizer = Utils.createLambda(finalizer);
498
+
499
+ return new Enumerable(function () {
500
+ var element;
501
+ return new IEnumerator(
502
+ function () { element = initializer(); },
503
+ function () { return this.yieldReturn(element); },
504
+ function () {
505
+ if (element != null) {
506
+ finalizer(element);
507
+ element = null;
508
+ }
509
+ });
510
+ });
511
+ };
512
+
513
+ // Overload:function(func)
514
+ // Overload:function(func, count)
515
+ Enumerable.generate = function (func, count) {
516
+ if (count != null)
517
+ return Enumerable.generate(func).take(count);
518
+
519
+ func = Utils.createLambda(func);
520
+
521
+ return new Enumerable(function () {
522
+ return new IEnumerator(
523
+ Functions.Blank,
524
+ function () { return this.yieldReturn(func()); },
525
+ Functions.Blank);
526
+ });
527
+ };
528
+
529
+ // Overload:function()
530
+ // Overload:function(start)
531
+ // Overload:function(start, step)
532
+ Enumerable.toInfinity = function (start, step) {
533
+ if (start == null) start = 0;
534
+ if (step == null) step = 1;
535
+
536
+ return new Enumerable(function () {
537
+ var value;
538
+ return new IEnumerator(
539
+ function () { value = start - step; },
540
+ function () { return this.yieldReturn(value += step); },
541
+ Functions.Blank);
542
+ });
543
+ };
544
+
545
+ // Overload:function()
546
+ // Overload:function(start)
547
+ // Overload:function(start, step)
548
+ Enumerable.toNegativeInfinity = function (start, step) {
549
+ if (start == null) start = 0;
550
+ if (step == null) step = 1;
551
+
552
+ return new Enumerable(function () {
553
+ var value;
554
+ return new IEnumerator(
555
+ function () { value = start + step; },
556
+ function () { return this.yieldReturn(value -= step); },
557
+ Functions.Blank);
558
+ });
559
+ };
560
+
561
+ Enumerable.unfold = function (seed, func) {
562
+ func = Utils.createLambda(func);
563
+
564
+ return new Enumerable(function () {
565
+ var isFirst = true;
566
+ var value;
567
+ return new IEnumerator(
568
+ Functions.Blank,
569
+ function () {
570
+ if (isFirst) {
571
+ isFirst = false;
572
+ value = seed;
573
+ return this.yieldReturn(value);
574
+ }
575
+ value = func(value);
576
+ return this.yieldReturn(value);
577
+ },
578
+ Functions.Blank);
579
+ });
580
+ };
581
+
582
+ Enumerable.defer = function (enumerableFactory) {
583
+ return new Enumerable(function () {
584
+ var enumerator;
585
+
586
+ return new IEnumerator(
587
+ function () { enumerator = Enumerable.from(enumerableFactory()).getEnumerator(); },
588
+ function () {
589
+ return (enumerator.moveNext())
590
+ ? this.yieldReturn(enumerator.current())
591
+ : this.yieldBreak();
592
+ },
593
+ function () {
594
+ Utils.dispose(enumerator);
595
+ });
596
+ });
597
+ };
598
+
599
+ /////////////////////
600
+ // Extension Methods
601
+
602
+ ////////////////////////////////////
603
+ // Projection and Filtering Methods
604
+
605
+ // Overload:function(func)
606
+ // Overload:function(func, resultSelector<element>)
607
+ // Overload:function(func, resultSelector<element, nestLevel>)
608
+ Enumerable.prototype.traverseBreadthFirst = function (func, resultSelector) {
609
+ var source = this;
610
+ func = Utils.createLambda(func);
611
+ resultSelector = Utils.createLambda(resultSelector);
612
+
613
+ return new Enumerable(function () {
614
+ var enumerator;
615
+ var nestLevel = 0;
616
+ var buffer = [];
617
+
618
+ return new IEnumerator(
619
+ function () { enumerator = source.getEnumerator(); },
620
+ function () {
621
+ while (true) {
622
+ if (enumerator.moveNext()) {
623
+ buffer.push(enumerator.current());
624
+ return this.yieldReturn(resultSelector(enumerator.current(), nestLevel));
625
+ }
626
+
627
+ const next = Enumerable.from(buffer).selectMany(function (x) { return func(x); });
628
+ if (!next.any()) {
629
+ return false;
630
+ }
631
+ else {
632
+ nestLevel++;
633
+ buffer = [];
634
+ Utils.dispose(enumerator);
635
+ enumerator = next.getEnumerator();
636
+ }
637
+ }
638
+ },
639
+ function () { Utils.dispose(enumerator); });
640
+ });
641
+ };
642
+
643
+ // Overload:function(func)
644
+ // Overload:function(func, resultSelector<element>)
645
+ // Overload:function(func, resultSelector<element, nestLevel>)
646
+ Enumerable.prototype.traverseDepthFirst = function (func, resultSelector) {
647
+ var source = this;
648
+ func = Utils.createLambda(func);
649
+ resultSelector = Utils.createLambda(resultSelector);
650
+
651
+ return new Enumerable(function () {
652
+ var enumeratorStack = [];
653
+ var enumerator;
654
+
655
+ return new IEnumerator(
656
+ function () { enumerator = source.getEnumerator(); },
657
+ function () {
658
+ while (true) {
659
+ if (enumerator.moveNext()) {
660
+ const value = resultSelector(enumerator.current(), enumeratorStack.length);
661
+ enumeratorStack.push(enumerator);
662
+ enumerator = Enumerable.from(func(enumerator.current())).getEnumerator();
663
+ return this.yieldReturn(value);
664
+ }
665
+
666
+ if (enumeratorStack.length <= 0) return false;
667
+ Utils.dispose(enumerator);
668
+ enumerator = enumeratorStack.pop();
669
+ }
670
+ },
671
+ function () {
672
+ try {
673
+ Utils.dispose(enumerator);
674
+ }
675
+ finally {
676
+ Enumerable.from(enumeratorStack).forEach(function (s) { s.dispose(); });
677
+ }
678
+ });
679
+ });
680
+ };
681
+
682
+ Enumerable.prototype.flatten = function () {
683
+ var source = this;
684
+
685
+ return new Enumerable(function () {
686
+ var enumerator;
687
+ var middleEnumerator = null;
688
+
689
+ return new IEnumerator(
690
+ function () { enumerator = source.getEnumerator(); },
691
+ function () {
692
+ while (true) {
693
+ if (middleEnumerator != null) {
694
+ if (middleEnumerator.moveNext()) {
695
+ return this.yieldReturn(middleEnumerator.current());
696
+ }
697
+ else {
698
+ middleEnumerator = null;
699
+ }
700
+ }
701
+
702
+ if (enumerator.moveNext()) {
703
+ if (enumerator.current() instanceof Array) {
704
+ Utils.dispose(middleEnumerator);
705
+ middleEnumerator = Enumerable.from(enumerator.current())
706
+ .selectMany(Functions.Identity)
707
+ .flatten()
708
+ .getEnumerator();
709
+ continue;
710
+ }
711
+ else {
712
+ return this.yieldReturn(enumerator.current());
713
+ }
714
+ }
715
+
716
+ return false;
717
+ }
718
+ },
719
+ function () {
720
+ try {
721
+ Utils.dispose(enumerator);
722
+ }
723
+ finally {
724
+ Utils.dispose(middleEnumerator);
725
+ }
726
+ });
727
+ });
728
+ };
729
+
730
+ Enumerable.prototype.pairwise = function (selector) {
731
+ var source = this;
732
+ selector = Utils.createLambda(selector);
733
+
734
+ return new Enumerable(function () {
735
+ var enumerator;
736
+
737
+ return new IEnumerator(
738
+ function () {
739
+ enumerator = source.getEnumerator();
740
+ enumerator.moveNext();
741
+ },
742
+ function () {
743
+ var prev = enumerator.current();
744
+ return (enumerator.moveNext())
745
+ ? this.yieldReturn(selector(prev, enumerator.current()))
746
+ : false;
747
+ },
748
+ function () { Utils.dispose(enumerator); });
749
+ });
750
+ };
751
+
752
+ // Overload:function(func)
753
+ // Overload:function(seed,func<value,element>)
754
+ Enumerable.prototype.scan = function (seed, func) {
755
+ var isUseSeed;
756
+ if (func == null) {
757
+ func = Utils.createLambda(seed);
758
+ isUseSeed = false;
759
+ } else {
760
+ func = Utils.createLambda(func);
761
+ isUseSeed = true;
762
+ }
763
+ var source = this;
764
+
765
+ return new Enumerable(function () {
766
+ var enumerator;
767
+ var value;
768
+ var isFirst = true;
769
+
770
+ return new IEnumerator(
771
+ function () { enumerator = source.getEnumerator(); },
772
+ function () {
773
+ if (isFirst) {
774
+ isFirst = false;
775
+ if (!isUseSeed) {
776
+ if (enumerator.moveNext()) {
777
+ return this.yieldReturn(value = enumerator.current());
778
+ }
779
+ }
780
+ else {
781
+ return this.yieldReturn(value = seed);
782
+ }
783
+ }
784
+
785
+ return (enumerator.moveNext())
786
+ ? this.yieldReturn(value = func(value, enumerator.current()))
787
+ : false;
788
+ },
789
+ function () { Utils.dispose(enumerator); });
790
+ });
791
+ };
792
+
793
+ // Overload:function(selector<element>)
794
+ // Overload:function(selector<element,index>)
795
+ Enumerable.prototype.select = function (selector) {
796
+ selector = Utils.createLambda(selector);
797
+
798
+ if (selector.length <= 1) {
799
+ return new WhereSelectEnumerable(this, null, selector);
800
+ }
801
+ else {
802
+ var source = this;
803
+
804
+ return new Enumerable(function () {
805
+ var enumerator;
806
+ var index = 0;
807
+
808
+ return new IEnumerator(
809
+ function () { enumerator = source.getEnumerator(); },
810
+ function () {
811
+ return (enumerator.moveNext())
812
+ ? this.yieldReturn(selector(enumerator.current(), index++))
813
+ : false;
814
+ },
815
+ function () { Utils.dispose(enumerator); });
816
+ });
817
+ }
818
+ };
819
+
820
+ // Overload:function(collectionSelector<element>)
821
+ // Overload:function(collectionSelector<element,index>)
822
+ // Overload:function(collectionSelector<element>,resultSelector)
823
+ // Overload:function(collectionSelector<element,index>,resultSelector)
824
+ Enumerable.prototype.selectMany = function (collectionSelector, resultSelector) {
825
+ var source = this;
826
+ collectionSelector = Utils.createLambda(collectionSelector);
827
+ if (resultSelector == null) resultSelector = function (a, b) { return b; };
828
+ resultSelector = Utils.createLambda(resultSelector);
829
+
830
+ return new Enumerable(function () {
831
+ var enumerator;
832
+ var middleEnumerator = undefined;
833
+ var index = 0;
834
+
835
+ return new IEnumerator(
836
+ function () { enumerator = source.getEnumerator(); },
837
+ function () {
838
+ if (middleEnumerator === undefined) {
839
+ if (!enumerator.moveNext()) return false;
840
+ }
841
+ do {
842
+ if (middleEnumerator == null) {
843
+ const middleSeq = collectionSelector(enumerator.current(), index++);
844
+ middleEnumerator = Enumerable.from(middleSeq).getEnumerator();
845
+ }
846
+ if (middleEnumerator.moveNext()) {
847
+ return this.yieldReturn(resultSelector(enumerator.current(), middleEnumerator.current()));
848
+ }
849
+ Utils.dispose(middleEnumerator);
850
+ middleEnumerator = null;
851
+ } while (enumerator.moveNext());
852
+ return false;
853
+ },
854
+ function () {
855
+ try {
856
+ Utils.dispose(enumerator);
857
+ }
858
+ finally {
859
+ Utils.dispose(middleEnumerator);
860
+ }
861
+ });
862
+ });
863
+ };
864
+
865
+ // Overload:function(predicate<element>)
866
+ // Overload:function(predicate<element,index>)
867
+ Enumerable.prototype.where = function (predicate) {
868
+ predicate = Utils.createLambda(predicate);
869
+
870
+ if (predicate.length <= 1) {
871
+ return new WhereEnumerable(this, predicate);
872
+ }
873
+ else {
874
+ var source = this;
875
+
876
+ return new Enumerable(function () {
877
+ var enumerator;
878
+ var index = 0;
879
+
880
+ return new IEnumerator(
881
+ function () { enumerator = source.getEnumerator(); },
882
+ function () {
883
+ while (enumerator.moveNext()) {
884
+ if (predicate(enumerator.current(), index++)) {
885
+ return this.yieldReturn(enumerator.current());
886
+ }
887
+ }
888
+ return false;
889
+ },
890
+ function () { Utils.dispose(enumerator); });
891
+ });
892
+ }
893
+ };
894
+
895
+
896
+ // Overload:function(selector<element>)
897
+ // Overload:function(selector<element,index>)
898
+ Enumerable.prototype.choose = function (selector) {
899
+ selector = Utils.createLambda(selector);
900
+ var source = this;
901
+
902
+ return new Enumerable(function () {
903
+ var enumerator;
904
+ var index = 0;
905
+
906
+ return new IEnumerator(
907
+ function () { enumerator = source.getEnumerator(); },
908
+ function () {
909
+ while (enumerator.moveNext()) {
910
+ const result = selector(enumerator.current(), index++);
911
+ if (result != null) {
912
+ return this.yieldReturn(result);
913
+ }
914
+ }
915
+ return this.yieldBreak();
916
+ },
917
+ function () { Utils.dispose(enumerator); });
918
+ });
919
+ };
920
+
921
+ Enumerable.prototype.ofType = function (type) {
922
+ var typeName;
923
+ switch (type) {
924
+ case Number:
925
+ typeName = Types.Number;
926
+ break;
927
+ case String:
928
+ typeName = Types.String;
929
+ break;
930
+ case Boolean:
931
+ typeName = Types.Boolean;
932
+ break;
933
+ case Function:
934
+ typeName = Types.Function;
935
+ break;
936
+ default:
937
+ typeName = null;
938
+ break;
939
+ }
940
+ return (typeName === null)
941
+ ? this.where(function (x) { return x instanceof type; })
942
+ : this.where(function (x) { return typeof x === typeName; });
943
+ };
944
+
945
+ // mutiple arguments, last one is selector, others are enumerable
946
+ Enumerable.prototype.zip = function () {
947
+ var args = arguments;
948
+ var selector = Utils.createLambda(arguments[arguments.length - 1]);
949
+
950
+ var source = this;
951
+ // optimized case:argument is 2
952
+ if (arguments.length == 2) {
953
+ const second = arguments[0];
954
+
955
+ return new Enumerable(function () {
956
+ var firstEnumerator;
957
+ var secondEnumerator;
958
+ var index = 0;
959
+
960
+ return new IEnumerator(
961
+ function () {
962
+ firstEnumerator = source.getEnumerator();
963
+ secondEnumerator = Enumerable.from(second).getEnumerator();
964
+ },
965
+ function () {
966
+ if (firstEnumerator.moveNext() && secondEnumerator.moveNext()) {
967
+ return this.yieldReturn(selector(firstEnumerator.current(), secondEnumerator.current(), index++));
968
+ }
969
+ return false;
970
+ },
971
+ function () {
972
+ try {
973
+ Utils.dispose(firstEnumerator);
974
+ } finally {
975
+ Utils.dispose(secondEnumerator);
976
+ }
977
+ });
978
+ });
979
+ }
980
+ else {
981
+ return new Enumerable(function () {
982
+ var enumerators;
983
+ var index = 0;
984
+
985
+ return new IEnumerator(
986
+ function () {
987
+ var array = Enumerable.make(source)
988
+ .concat(Enumerable.from(args).takeExceptLast().select(Enumerable.from))
989
+ .select(function (x) { return x.getEnumerator() })
990
+ .toArray();
991
+ enumerators = Enumerable.from(array);
992
+ },
993
+ function () {
994
+ if (enumerators.all(function (x) { return x.moveNext() })) {
995
+ const array = enumerators
996
+ .select(function (x) { return x.current() })
997
+ .toArray();
998
+ array.push(index++);
999
+ return this.yieldReturn(selector.apply(null, array));
1000
+ }
1001
+ else {
1002
+ return this.yieldBreak();
1003
+ }
1004
+ },
1005
+ function () {
1006
+ Enumerable.from(enumerators).forEach(Utils.dispose);
1007
+ });
1008
+ });
1009
+ }
1010
+ };
1011
+
1012
+ // mutiple arguments
1013
+ Enumerable.prototype.merge = function () {
1014
+ var args = arguments;
1015
+ var source = this;
1016
+
1017
+ return new Enumerable(function () {
1018
+ var enumerators;
1019
+ var index = -1;
1020
+
1021
+ return new IEnumerator(
1022
+ function () {
1023
+ enumerators = Enumerable.make(source)
1024
+ .concat(Enumerable.from(args).select(Enumerable.from))
1025
+ .select(function (x) { return x.getEnumerator() })
1026
+ .toArray();
1027
+ },
1028
+ function () {
1029
+ while (enumerators.length > 0) {
1030
+ index = (index >= enumerators.length - 1) ? 0 : index + 1;
1031
+ const enumerator = enumerators[index];
1032
+
1033
+ if (enumerator.moveNext()) {
1034
+ return this.yieldReturn(enumerator.current());
1035
+ }
1036
+ else {
1037
+ enumerator.dispose();
1038
+ enumerators.splice(index--, 1);
1039
+ }
1040
+ }
1041
+ return this.yieldBreak();
1042
+ },
1043
+ function () {
1044
+ Enumerable.from(enumerators).forEach(Utils.dispose);
1045
+ });
1046
+ });
1047
+ };
1048
+
1049
+ ////////////////
1050
+ // Join Methods
1051
+
1052
+ // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector)
1053
+ // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
1054
+ Enumerable.prototype.join = function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector) {
1055
+ outerKeySelector = Utils.createLambda(outerKeySelector);
1056
+ innerKeySelector = Utils.createLambda(innerKeySelector);
1057
+ resultSelector = Utils.createLambda(resultSelector);
1058
+ compareSelector = Utils.createLambda(compareSelector);
1059
+ var source = this;
1060
+
1061
+ return new Enumerable(function () {
1062
+ var outerEnumerator;
1063
+ var lookup;
1064
+ var innerElements = null;
1065
+ var innerCount = 0;
1066
+
1067
+ return new IEnumerator(
1068
+ function () {
1069
+ outerEnumerator = source.getEnumerator();
1070
+ lookup = Enumerable.from(inner).toLookup(innerKeySelector, Functions.Identity, compareSelector);
1071
+ },
1072
+ function () {
1073
+ while (true) {
1074
+ if (innerElements != null) {
1075
+ let innerElement = innerElements[innerCount++];
1076
+ if (innerElement !== undefined) {
1077
+ return this.yieldReturn(resultSelector(outerEnumerator.current(), innerElement));
1078
+ }
1079
+
1080
+ innerElement = null;
1081
+ innerCount = 0;
1082
+ }
1083
+
1084
+ if (outerEnumerator.moveNext()) {
1085
+ const key = outerKeySelector(outerEnumerator.current());
1086
+ innerElements = lookup.get(key).toArray();
1087
+ } else {
1088
+ return false;
1089
+ }
1090
+ }
1091
+ },
1092
+ function () { Utils.dispose(outerEnumerator); });
1093
+ });
1094
+ };
1095
+
1096
+ // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector)
1097
+ // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
1098
+ Enumerable.prototype.leftJoin = function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector) {
1099
+ outerKeySelector = Utils.createLambda(outerKeySelector);
1100
+ innerKeySelector = Utils.createLambda(innerKeySelector);
1101
+ resultSelector = Utils.createLambda(resultSelector);
1102
+ compareSelector = Utils.createLambda(compareSelector);
1103
+ var source = this;
1104
+
1105
+ return new Enumerable(function () {
1106
+ var outerEnumerator;
1107
+ var lookup;
1108
+ var innerElements = null;
1109
+ var innerCount = 0;
1110
+
1111
+ return new IEnumerator(
1112
+ function () {
1113
+ outerEnumerator = source.getEnumerator();
1114
+ lookup = Enumerable.from(inner).toLookup(innerKeySelector, Functions.Identity, compareSelector);
1115
+ },
1116
+ function () {
1117
+ while (true) {
1118
+ if (innerElements != null) {
1119
+ let innerElement = innerElements[innerCount++];
1120
+ if (innerElement !== undefined) {
1121
+ return this.yieldReturn(resultSelector(outerEnumerator.current(), innerElement));
1122
+ }
1123
+
1124
+ innerElement = null;
1125
+ innerCount = 0;
1126
+ }
1127
+
1128
+ if (outerEnumerator.moveNext()) {
1129
+ const key = outerKeySelector(outerEnumerator.current());
1130
+ innerElements = lookup.get(key).toArray();
1131
+ // execute once if innerElements is NULL
1132
+ if (innerElements == null || innerElements.length == 0) {
1133
+ return this.yieldReturn(resultSelector(outerEnumerator.current(), null));
1134
+ }
1135
+ } else {
1136
+ return false;
1137
+ }
1138
+ }
1139
+ },
1140
+ function () { Utils.dispose(outerEnumerator); });
1141
+ });
1142
+ };
1143
+
1144
+ // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector)
1145
+ // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
1146
+ Enumerable.prototype.groupJoin = function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector) {
1147
+ outerKeySelector = Utils.createLambda(outerKeySelector);
1148
+ innerKeySelector = Utils.createLambda(innerKeySelector);
1149
+ resultSelector = Utils.createLambda(resultSelector);
1150
+ compareSelector = Utils.createLambda(compareSelector);
1151
+ var source = this;
1152
+
1153
+ return new Enumerable(function () {
1154
+ var enumerator = source.getEnumerator();
1155
+ var lookup = null;
1156
+
1157
+ return new IEnumerator(
1158
+ function () {
1159
+ enumerator = source.getEnumerator();
1160
+ lookup = Enumerable.from(inner).toLookup(innerKeySelector, Functions.Identity, compareSelector);
1161
+ },
1162
+ function () {
1163
+ if (enumerator.moveNext()) {
1164
+ const innerElement = lookup.get(outerKeySelector(enumerator.current()));
1165
+ return this.yieldReturn(resultSelector(enumerator.current(), innerElement));
1166
+ }
1167
+ return false;
1168
+ },
1169
+ function () { Utils.dispose(enumerator); });
1170
+ });
1171
+ };
1172
+
1173
+ ///////////////
1174
+ // Set Methods
1175
+
1176
+ Enumerable.prototype.all = function (predicate) {
1177
+ predicate = Utils.createLambda(predicate);
1178
+
1179
+ var result = true;
1180
+ this.forEach(function (x) {
1181
+ if (!predicate(x)) {
1182
+ result = false;
1183
+ return false; // break
1184
+ }
1185
+ });
1186
+ return result;
1187
+ };
1188
+
1189
+ // Overload:function()
1190
+ // Overload:function(predicate)
1191
+ Enumerable.prototype.any = function (predicate) {
1192
+ predicate = Utils.createLambda(predicate);
1193
+
1194
+ var enumerator = this.getEnumerator();
1195
+ try {
1196
+ if (arguments.length == 0) return enumerator.moveNext(); // case:function()
1197
+
1198
+ while (enumerator.moveNext()) // case:function(predicate)
1199
+ {
1200
+ if (predicate(enumerator.current())) return true;
1201
+ }
1202
+ return false;
1203
+ }
1204
+ finally {
1205
+ Utils.dispose(enumerator);
1206
+ }
1207
+ };
1208
+
1209
+ Enumerable.prototype.isEmpty = function () {
1210
+ return !this.any();
1211
+ };
1212
+
1213
+ // multiple arguments
1214
+ Enumerable.prototype.concat = function () {
1215
+ var source = this;
1216
+
1217
+ if (arguments.length == 1) {
1218
+ const second = arguments[0];
1219
+
1220
+ return new Enumerable(function () {
1221
+ var firstEnumerator;
1222
+ var secondEnumerator;
1223
+
1224
+ return new IEnumerator(
1225
+ function () { firstEnumerator = source.getEnumerator(); },
1226
+ function () {
1227
+ if (secondEnumerator == null) {
1228
+ if (firstEnumerator.moveNext()) return this.yieldReturn(firstEnumerator.current());
1229
+ secondEnumerator = Enumerable.from(second).getEnumerator();
1230
+ }
1231
+ if (secondEnumerator.moveNext()) return this.yieldReturn(secondEnumerator.current());
1232
+ return false;
1233
+ },
1234
+ function () {
1235
+ try {
1236
+ Utils.dispose(firstEnumerator);
1237
+ }
1238
+ finally {
1239
+ Utils.dispose(secondEnumerator);
1240
+ }
1241
+ });
1242
+ });
1243
+ }
1244
+ else {
1245
+ const args = arguments;
1246
+
1247
+ return new Enumerable(function () {
1248
+ var enumerators;
1249
+
1250
+ return new IEnumerator(
1251
+ function () {
1252
+ enumerators = Enumerable.make(source)
1253
+ .concat(Enumerable.from(args).select(Enumerable.from))
1254
+ .select(function (x) { return x.getEnumerator() })
1255
+ .toArray();
1256
+ },
1257
+ function () {
1258
+ while (enumerators.length > 0) {
1259
+ const enumerator = enumerators[0];
1260
+
1261
+ if (enumerator.moveNext()) {
1262
+ return this.yieldReturn(enumerator.current());
1263
+ }
1264
+ else {
1265
+ enumerator.dispose();
1266
+ enumerators.splice(0, 1);
1267
+ }
1268
+ }
1269
+ return this.yieldBreak();
1270
+ },
1271
+ function () {
1272
+ Enumerable.from(enumerators).forEach(Utils.dispose);
1273
+ });
1274
+ });
1275
+ }
1276
+ };
1277
+
1278
+ Enumerable.prototype.insert = function (index, second) {
1279
+ var source = this;
1280
+
1281
+ return new Enumerable(function () {
1282
+ var firstEnumerator;
1283
+ var secondEnumerator;
1284
+ var count = 0;
1285
+ var isEnumerated = false;
1286
+
1287
+ return new IEnumerator(
1288
+ function () {
1289
+ firstEnumerator = source.getEnumerator();
1290
+ secondEnumerator = Enumerable.from(second).getEnumerator();
1291
+ },
1292
+ function () {
1293
+ if (count == index && secondEnumerator.moveNext()) {
1294
+ isEnumerated = true;
1295
+ return this.yieldReturn(secondEnumerator.current());
1296
+ }
1297
+ if (firstEnumerator.moveNext()) {
1298
+ count++;
1299
+ return this.yieldReturn(firstEnumerator.current());
1300
+ }
1301
+ if (!isEnumerated && secondEnumerator.moveNext()) {
1302
+ return this.yieldReturn(secondEnumerator.current());
1303
+ }
1304
+ return false;
1305
+ },
1306
+ function () {
1307
+ try {
1308
+ Utils.dispose(firstEnumerator);
1309
+ }
1310
+ finally {
1311
+ Utils.dispose(secondEnumerator);
1312
+ }
1313
+ });
1314
+ });
1315
+ };
1316
+
1317
+ Enumerable.prototype.alternate = function (alternateValueOrSequence) {
1318
+ var source = this;
1319
+
1320
+ return new Enumerable(function () {
1321
+ var buffer;
1322
+ var enumerator;
1323
+ var alternateSequence;
1324
+ var alternateEnumerator;
1325
+
1326
+ return new IEnumerator(
1327
+ function () {
1328
+ if (alternateValueOrSequence instanceof Array || alternateValueOrSequence.getEnumerator != null) {
1329
+ alternateSequence = Enumerable.from(Enumerable.from(alternateValueOrSequence).toArray()); // freeze
1330
+ }
1331
+ else {
1332
+ alternateSequence = Enumerable.make(alternateValueOrSequence);
1333
+ }
1334
+ enumerator = source.getEnumerator();
1335
+ if (enumerator.moveNext()) buffer = enumerator.current();
1336
+ },
1337
+ function () {
1338
+ while (true) {
1339
+ if (alternateEnumerator != null) {
1340
+ if (alternateEnumerator.moveNext()) {
1341
+ return this.yieldReturn(alternateEnumerator.current());
1342
+ }
1343
+ else {
1344
+ alternateEnumerator = null;
1345
+ }
1346
+ }
1347
+
1348
+ if (buffer == null && enumerator.moveNext()) {
1349
+ buffer = enumerator.current(); // hasNext
1350
+ alternateEnumerator = alternateSequence.getEnumerator();
1351
+ continue; // GOTO
1352
+ }
1353
+ else if (buffer != null) {
1354
+ const retVal = buffer;
1355
+ buffer = null;
1356
+ return this.yieldReturn(retVal);
1357
+ }
1358
+
1359
+ return this.yieldBreak();
1360
+ }
1361
+ },
1362
+ function () {
1363
+ try {
1364
+ Utils.dispose(enumerator);
1365
+ }
1366
+ finally {
1367
+ Utils.dispose(alternateEnumerator);
1368
+ }
1369
+ });
1370
+ });
1371
+ };
1372
+
1373
+ // Overload:function(value)
1374
+ // Overload:function(value, compareSelector)
1375
+ Enumerable.prototype.contains = function (value, compareSelector) {
1376
+ compareSelector = Utils.createLambda(compareSelector);
1377
+ var enumerator = this.getEnumerator();
1378
+ try {
1379
+ while (enumerator.moveNext()) {
1380
+ if (compareSelector(enumerator.current()) === value) return true;
1381
+ }
1382
+ return false;
1383
+ }
1384
+ finally {
1385
+ Utils.dispose(enumerator);
1386
+ }
1387
+ };
1388
+
1389
+ Enumerable.prototype.defaultIfEmpty = function (defaultValue) {
1390
+ var source = this;
1391
+ if (defaultValue === undefined) defaultValue = null;
1392
+
1393
+ return new Enumerable(function () {
1394
+ var enumerator;
1395
+ var isFirst = true;
1396
+
1397
+ return new IEnumerator(
1398
+ function () { enumerator = source.getEnumerator(); },
1399
+ function () {
1400
+ if (enumerator.moveNext()) {
1401
+ isFirst = false;
1402
+ return this.yieldReturn(enumerator.current());
1403
+ }
1404
+ else if (isFirst) {
1405
+ isFirst = false;
1406
+ return this.yieldReturn(defaultValue);
1407
+ }
1408
+ return false;
1409
+ },
1410
+ function () { Utils.dispose(enumerator); });
1411
+ });
1412
+ };
1413
+
1414
+ // Overload:function()
1415
+ // Overload:function(compareSelector)
1416
+ Enumerable.prototype.distinct = function (compareSelector) {
1417
+ return this.except(Enumerable.empty(), compareSelector);
1418
+ };
1419
+
1420
+ Enumerable.prototype.distinctUntilChanged = function (compareSelector) {
1421
+ compareSelector = Utils.createLambda(compareSelector);
1422
+ var source = this;
1423
+
1424
+ return new Enumerable(function () {
1425
+ var enumerator;
1426
+ var compareKey;
1427
+ var initial;
1428
+
1429
+ return new IEnumerator(
1430
+ function () {
1431
+ enumerator = source.getEnumerator();
1432
+ },
1433
+ function () {
1434
+ while (enumerator.moveNext()) {
1435
+ const key = compareSelector(enumerator.current());
1436
+
1437
+ if (initial) {
1438
+ initial = false;
1439
+ compareKey = key;
1440
+ return this.yieldReturn(enumerator.current());
1441
+ }
1442
+
1443
+ if (compareKey === key) {
1444
+ continue;
1445
+ }
1446
+
1447
+ compareKey = key;
1448
+ return this.yieldReturn(enumerator.current());
1449
+ }
1450
+ return this.yieldBreak();
1451
+ },
1452
+ function () { Utils.dispose(enumerator); });
1453
+ });
1454
+ };
1455
+
1456
+ // Overload:function(second)
1457
+ // Overload:function(second, compareSelector)
1458
+ Enumerable.prototype.except = function (second, compareSelector) {
1459
+ compareSelector = Utils.createLambda(compareSelector);
1460
+ var source = this;
1461
+
1462
+ return new Enumerable(function () {
1463
+ var enumerator;
1464
+ var keys;
1465
+
1466
+ return new IEnumerator(
1467
+ function () {
1468
+ enumerator = source.getEnumerator();
1469
+ keys = new Dictionary(compareSelector);
1470
+ Enumerable.from(second).forEach(function (key) { keys.add(key); });
1471
+ },
1472
+ function () {
1473
+ while (enumerator.moveNext()) {
1474
+ const current = enumerator.current();
1475
+ if (!keys.contains(current)) {
1476
+ keys.add(current);
1477
+ return this.yieldReturn(current);
1478
+ }
1479
+ }
1480
+ return false;
1481
+ },
1482
+ function () { Utils.dispose(enumerator); });
1483
+ });
1484
+ };
1485
+
1486
+ // Overload:function(second)
1487
+ // Overload:function(second, compareSelector)
1488
+ Enumerable.prototype.intersect = function (second, compareSelector) {
1489
+ compareSelector = Utils.createLambda(compareSelector);
1490
+ var source = this;
1491
+
1492
+ return new Enumerable(function () {
1493
+ var enumerator;
1494
+ var keys;
1495
+ var outs;
1496
+
1497
+ return new IEnumerator(
1498
+ function () {
1499
+ enumerator = source.getEnumerator();
1500
+
1501
+ keys = new Dictionary(compareSelector);
1502
+ Enumerable.from(second).forEach(function (key) { keys.add(key); });
1503
+ outs = new Dictionary(compareSelector);
1504
+ },
1505
+ function () {
1506
+ while (enumerator.moveNext()) {
1507
+ const current = enumerator.current();
1508
+ if (!outs.contains(current) && keys.contains(current)) {
1509
+ outs.add(current);
1510
+ return this.yieldReturn(current);
1511
+ }
1512
+ }
1513
+ return false;
1514
+ },
1515
+ function () { Utils.dispose(enumerator); });
1516
+ });
1517
+ };
1518
+
1519
+ // Overload:function(second)
1520
+ // Overload:function(second, compareSelector)
1521
+ Enumerable.prototype.sequenceEqual = function (second, compareSelector) {
1522
+ compareSelector = Utils.createLambda(compareSelector);
1523
+
1524
+ var firstEnumerator = this.getEnumerator();
1525
+ try {
1526
+ const secondEnumerator = Enumerable.from(second).getEnumerator();
1527
+ try {
1528
+ while (firstEnumerator.moveNext()) {
1529
+ if (!secondEnumerator.moveNext()
1530
+ || compareSelector(firstEnumerator.current()) !== compareSelector(secondEnumerator.current())) {
1531
+ return false;
1532
+ }
1533
+ }
1534
+
1535
+ if (secondEnumerator.moveNext()) return false;
1536
+ return true;
1537
+ }
1538
+ finally {
1539
+ Utils.dispose(secondEnumerator);
1540
+ }
1541
+ }
1542
+ finally {
1543
+ Utils.dispose(firstEnumerator);
1544
+ }
1545
+ };
1546
+
1547
+ Enumerable.prototype.union = function (second, compareSelector) {
1548
+ compareSelector = Utils.createLambda(compareSelector);
1549
+ var source = this;
1550
+
1551
+ return new Enumerable(function () {
1552
+ var firstEnumerator;
1553
+ var secondEnumerator;
1554
+ var keys;
1555
+
1556
+ return new IEnumerator(
1557
+ function () {
1558
+ firstEnumerator = source.getEnumerator();
1559
+ keys = new Dictionary(compareSelector);
1560
+ },
1561
+ function () {
1562
+ var current;
1563
+ if (secondEnumerator === undefined) {
1564
+ while (firstEnumerator.moveNext()) {
1565
+ current = firstEnumerator.current();
1566
+ if (!keys.contains(current)) {
1567
+ keys.add(current);
1568
+ return this.yieldReturn(current);
1569
+ }
1570
+ }
1571
+ secondEnumerator = Enumerable.from(second).getEnumerator();
1572
+ }
1573
+ while (secondEnumerator.moveNext()) {
1574
+ current = secondEnumerator.current();
1575
+ if (!keys.contains(current)) {
1576
+ keys.add(current);
1577
+ return this.yieldReturn(current);
1578
+ }
1579
+ }
1580
+ return false;
1581
+ },
1582
+ function () {
1583
+ try {
1584
+ Utils.dispose(firstEnumerator);
1585
+ }
1586
+ finally {
1587
+ Utils.dispose(secondEnumerator);
1588
+ }
1589
+ });
1590
+ });
1591
+ };
1592
+
1593
+ ////////////////////
1594
+ // Ordering Methods
1595
+
1596
+ Enumerable.prototype.orderBy = function (keySelector, comparer) {
1597
+ return new OrderedEnumerable(this, keySelector, comparer, false);
1598
+ };
1599
+
1600
+ Enumerable.prototype.orderByDescending = function (keySelector, comparer) {
1601
+ return new OrderedEnumerable(this, keySelector, comparer, true);
1602
+ };
1603
+
1604
+ Enumerable.prototype.reverse = function () {
1605
+ var source = this;
1606
+
1607
+ return new Enumerable(function () {
1608
+ var buffer;
1609
+ var index;
1610
+
1611
+ return new IEnumerator(
1612
+ function () {
1613
+ buffer = source.toArray();
1614
+ index = buffer.length;
1615
+ },
1616
+ function () {
1617
+ return (index > 0)
1618
+ ? this.yieldReturn(buffer[--index])
1619
+ : false;
1620
+ },
1621
+ Functions.Blank);
1622
+ });
1623
+ };
1624
+
1625
+ Enumerable.prototype.shuffle = function () {
1626
+ var source = this;
1627
+
1628
+ return new Enumerable(function () {
1629
+ var buffer;
1630
+
1631
+ return new IEnumerator(
1632
+ function () { buffer = source.toArray(); },
1633
+ function () {
1634
+ if (buffer.length > 0) {
1635
+ const i = Math.floor(Math.random() * buffer.length);
1636
+ return this.yieldReturn(buffer.splice(i, 1)[0]);
1637
+ }
1638
+ return false;
1639
+ },
1640
+ Functions.Blank);
1641
+ });
1642
+ };
1643
+
1644
+ Enumerable.prototype.weightedSample = function (weightSelector) {
1645
+ weightSelector = Utils.createLambda(weightSelector);
1646
+ var source = this;
1647
+
1648
+ return new Enumerable(function () {
1649
+ var sortedByBound;
1650
+ var totalWeight = 0;
1651
+
1652
+ return new IEnumerator(
1653
+ function () {
1654
+ sortedByBound = source
1655
+ .choose(function (x) {
1656
+ var weight = weightSelector(x);
1657
+ if (weight <= 0) return null; // ignore 0
1658
+
1659
+ totalWeight += weight;
1660
+ return { value: x, bound: totalWeight };
1661
+ })
1662
+ .toArray();
1663
+ },
1664
+ function () {
1665
+ if (sortedByBound.length > 0) {
1666
+ const draw = Math.floor(Math.random() * totalWeight) + 1;
1667
+
1668
+ let lower = -1;
1669
+ let upper = sortedByBound.length;
1670
+ while (upper - lower > 1) {
1671
+ const index = Math.floor((lower + upper) / 2);
1672
+ if (sortedByBound[index].bound >= draw) {
1673
+ upper = index;
1674
+ }
1675
+ else {
1676
+ lower = index;
1677
+ }
1678
+ }
1679
+
1680
+ return this.yieldReturn(sortedByBound[upper].value);
1681
+ }
1682
+
1683
+ return this.yieldBreak();
1684
+ },
1685
+ Functions.Blank);
1686
+ });
1687
+ };
1688
+
1689
+ ////////////////////
1690
+ // Grouping Methods
1691
+
1692
+ // Overload:function(keySelector)
1693
+ // Overload:function(keySelector,elementSelector)
1694
+ // Overload:function(keySelector,elementSelector,resultSelector)
1695
+ // Overload:function(keySelector,elementSelector,resultSelector,compareSelector)
1696
+ Enumerable.prototype.groupBy = function (keySelector, elementSelector, resultSelector, compareSelector) {
1697
+ var source = this;
1698
+ keySelector = Utils.createLambda(keySelector);
1699
+ elementSelector = Utils.createLambda(elementSelector);
1700
+ if (resultSelector != null) resultSelector = Utils.createLambda(resultSelector);
1701
+ compareSelector = Utils.createLambda(compareSelector);
1702
+
1703
+ return new Enumerable(function () {
1704
+ var enumerator;
1705
+
1706
+ return new IEnumerator(
1707
+ function () {
1708
+ enumerator = source.toLookup(keySelector, elementSelector, compareSelector)
1709
+ .toEnumerable()
1710
+ .getEnumerator();
1711
+ },
1712
+ function () {
1713
+ while (enumerator.moveNext()) {
1714
+ return (resultSelector == null)
1715
+ ? this.yieldReturn(enumerator.current())
1716
+ : this.yieldReturn(resultSelector(enumerator.current().key(), enumerator.current()));
1717
+ }
1718
+ return false;
1719
+ },
1720
+ function () { Utils.dispose(enumerator); });
1721
+ });
1722
+ };
1723
+
1724
+ // Overload:function(keySelector)
1725
+ // Overload:function(keySelector,elementSelector)
1726
+ // Overload:function(keySelector,elementSelector,resultSelector)
1727
+ // Overload:function(keySelector,elementSelector,resultSelector,compareSelector)
1728
+ Enumerable.prototype.partitionBy = function (keySelector, elementSelector, resultSelector, compareSelector) {
1729
+ var source = this;
1730
+ keySelector = Utils.createLambda(keySelector);
1731
+ elementSelector = Utils.createLambda(elementSelector);
1732
+ compareSelector = Utils.createLambda(compareSelector);
1733
+ var hasResultSelector;
1734
+ if (resultSelector == null) {
1735
+ hasResultSelector = false;
1736
+ resultSelector = function (key, group) { return new Grouping(key, group); };
1737
+ }
1738
+ else {
1739
+ hasResultSelector = true;
1740
+ resultSelector = Utils.createLambda(resultSelector);
1741
+ }
1742
+
1743
+ return new Enumerable(function () {
1744
+ var enumerator;
1745
+ var key;
1746
+ var compareKey;
1747
+ var group = [];
1748
+
1749
+ return new IEnumerator(
1750
+ function () {
1751
+ enumerator = source.getEnumerator();
1752
+ if (enumerator.moveNext()) {
1753
+ key = keySelector(enumerator.current());
1754
+ compareKey = compareSelector(key);
1755
+ group.push(elementSelector(enumerator.current()));
1756
+ }
1757
+ },
1758
+ function () {
1759
+ var hasNext;
1760
+ while ((hasNext = enumerator.moveNext()) == true) {
1761
+ if (compareKey === compareSelector(keySelector(enumerator.current()))) {
1762
+ group.push(elementSelector(enumerator.current()));
1763
+ }
1764
+ else break;
1765
+ }
1766
+
1767
+ if (group.length > 0) {
1768
+ const result = (hasResultSelector)
1769
+ ? resultSelector(key, Enumerable.from(group))
1770
+ : resultSelector(key, group);
1771
+ if (hasNext) {
1772
+ key = keySelector(enumerator.current());
1773
+ compareKey = compareSelector(key);
1774
+ group = [elementSelector(enumerator.current())];
1775
+ }
1776
+ else group = [];
1777
+
1778
+ return this.yieldReturn(result);
1779
+ }
1780
+
1781
+ return false;
1782
+ },
1783
+ function () { Utils.dispose(enumerator); });
1784
+ });
1785
+ };
1786
+
1787
+ Enumerable.prototype.buffer = function (count) {
1788
+ var source = this;
1789
+
1790
+ return new Enumerable(function () {
1791
+ var enumerator;
1792
+
1793
+ return new IEnumerator(
1794
+ function () { enumerator = source.getEnumerator(); },
1795
+ function () {
1796
+ var array = [];
1797
+ var index = 0;
1798
+ while (enumerator.moveNext()) {
1799
+ array.push(enumerator.current());
1800
+ if (++index >= count) return this.yieldReturn(array);
1801
+ }
1802
+ if (array.length > 0) return this.yieldReturn(array);
1803
+ return false;
1804
+ },
1805
+ function () { Utils.dispose(enumerator); });
1806
+ });
1807
+ };
1808
+
1809
+ /////////////////////
1810
+ // Aggregate Methods
1811
+
1812
+ // Overload:function(func)
1813
+ // Overload:function(seed,func)
1814
+ // Overload:function(seed,func,resultSelector)
1815
+ Enumerable.prototype.aggregate = function (seed, func, resultSelector) {
1816
+ resultSelector = Utils.createLambda(resultSelector);
1817
+ return resultSelector(this.scan(seed, func, resultSelector).last());
1818
+ };
1819
+
1820
+ // Overload:function()
1821
+ // Overload:function(selector)
1822
+ Enumerable.prototype.average = function (selector) {
1823
+ selector = Utils.createLambda(selector);
1824
+
1825
+ var sum = 0;
1826
+ var count = 0;
1827
+ this.forEach(function (x) {
1828
+ sum += selector(x);
1829
+ ++count;
1830
+ });
1831
+
1832
+ return sum / count;
1833
+ };
1834
+
1835
+ // Overload:function()
1836
+ // Overload:function(predicate)
1837
+ Enumerable.prototype.count = function (predicate) {
1838
+ predicate = (predicate == null) ? Functions.True : Utils.createLambda(predicate);
1839
+
1840
+ var count = 0;
1841
+ this.forEach(function (x, i) {
1842
+ if (predicate(x, i)) ++count;
1843
+ });
1844
+ return count;
1845
+ };
1846
+
1847
+ // Overload:function()
1848
+ // Overload:function(selector)
1849
+ Enumerable.prototype.max = function (selector) {
1850
+ if (selector == null) selector = Functions.Identity;
1851
+ return this.select(selector).aggregate(function (a, b) { return (a > b) ? a : b; });
1852
+ };
1853
+
1854
+ // Overload:function()
1855
+ // Overload:function(selector)
1856
+ Enumerable.prototype.min = function (selector) {
1857
+ if (selector == null) selector = Functions.Identity;
1858
+ return this.select(selector).aggregate(function (a, b) { return (a < b) ? a : b; });
1859
+ };
1860
+
1861
+ Enumerable.prototype.maxBy = function (keySelector) {
1862
+ keySelector = Utils.createLambda(keySelector);
1863
+ return this.aggregate(function (a, b) { return (keySelector(a) > keySelector(b)) ? a : b; });
1864
+ };
1865
+
1866
+ Enumerable.prototype.minBy = function (keySelector) {
1867
+ keySelector = Utils.createLambda(keySelector);
1868
+ return this.aggregate(function (a, b) { return (keySelector(a) < keySelector(b)) ? a : b; });
1869
+ };
1870
+
1871
+ // Overload:function()
1872
+ // Overload:function(selector)
1873
+ Enumerable.prototype.sum = function (selector) {
1874
+ if (selector == null) selector = Functions.Identity;
1875
+ return this.select(selector).aggregate(0, function (a, b) { return a + b; });
1876
+ };
1877
+
1878
+ //////////////////
1879
+ // Paging Methods
1880
+
1881
+ Enumerable.prototype.elementAt = function (index) {
1882
+ var value;
1883
+ var found = false;
1884
+ this.forEach(function (x, i) {
1885
+ if (i == index) {
1886
+ value = x;
1887
+ found = true;
1888
+ return false;
1889
+ }
1890
+ });
1891
+
1892
+ if (!found) throw new Error("index is less than 0 or greater than or equal to the number of elements in source.");
1893
+ return value;
1894
+ };
1895
+
1896
+ Enumerable.prototype.elementAtOrDefault = function (index, defaultValue) {
1897
+ if (defaultValue === undefined) defaultValue = null;
1898
+ var value;
1899
+ var found = false;
1900
+ this.forEach(function (x, i) {
1901
+ if (i == index) {
1902
+ value = x;
1903
+ found = true;
1904
+ return false;
1905
+ }
1906
+ });
1907
+
1908
+ return (!found) ? defaultValue : value;
1909
+ };
1910
+
1911
+ // Overload:function()
1912
+ // Overload:function(predicate)
1913
+ Enumerable.prototype.first = function (predicate) {
1914
+ if (predicate != null) return this.where(predicate).first();
1915
+
1916
+ var value;
1917
+ var found = false;
1918
+ this.forEach(function (x) {
1919
+ value = x;
1920
+ found = true;
1921
+ return false;
1922
+ });
1923
+
1924
+ if (!found) throw new Error("first:No element satisfies the condition.");
1925
+ return value;
1926
+ };
1927
+
1928
+ Enumerable.prototype.firstOrDefault = function (predicate, defaultValue) {
1929
+ if (predicate !== undefined) {
1930
+ if (typeof predicate === Types.Function || typeof Utils.createLambda(predicate) === Types.Function) {
1931
+ return this.where(predicate).firstOrDefault(undefined, defaultValue);
1932
+ }
1933
+ defaultValue = predicate;
1934
+ }
1935
+
1936
+ var value;
1937
+ var found = false;
1938
+ this.forEach(function (x) {
1939
+ value = x;
1940
+ found = true;
1941
+ return false;
1942
+ });
1943
+ return (!found) ? defaultValue : value;
1944
+ };
1945
+
1946
+ // Overload:function()
1947
+ // Overload:function(predicate)
1948
+ Enumerable.prototype.last = function (predicate) {
1949
+ if (predicate != null) return this.where(predicate).last();
1950
+
1951
+ var value;
1952
+ var found = false;
1953
+ this.forEach(function (x) {
1954
+ found = true;
1955
+ value = x;
1956
+ });
1957
+
1958
+ if (!found) throw new Error("last:No element satisfies the condition.");
1959
+ return value;
1960
+ };
1961
+
1962
+ Enumerable.prototype.lastOrDefault = function (predicate, defaultValue) {
1963
+ if (predicate !== undefined) {
1964
+ if (typeof predicate === Types.Function || typeof Utils.createLambda(predicate) === Types.Function) {
1965
+ return this.where(predicate).lastOrDefault(undefined, defaultValue);
1966
+ }
1967
+ defaultValue = predicate;
1968
+ }
1969
+
1970
+ var value;
1971
+ var found = false;
1972
+ this.forEach(function (x) {
1973
+ found = true;
1974
+ value = x;
1975
+ });
1976
+ return (!found) ? defaultValue : value;
1977
+ };
1978
+
1979
+ // Overload:function()
1980
+ // Overload:function(predicate)
1981
+ Enumerable.prototype.single = function (predicate) {
1982
+ if (predicate != null) return this.where(predicate).single();
1983
+
1984
+ var value;
1985
+ var found = false;
1986
+ this.forEach(function (x) {
1987
+ if (!found) {
1988
+ found = true;
1989
+ value = x;
1990
+ } else throw new Error("single:sequence contains more than one element.");
1991
+ });
1992
+
1993
+ if (!found) throw new Error("single:No element satisfies the condition.");
1994
+ return value;
1995
+ };
1996
+
1997
+ // Overload:function(defaultValue)
1998
+ // Overload:function(defaultValue,predicate)
1999
+ Enumerable.prototype.singleOrDefault = function (predicate, defaultValue) {
2000
+ if (defaultValue === undefined) defaultValue = null;
2001
+ if (predicate != null) return this.where(predicate).singleOrDefault(null, defaultValue);
2002
+
2003
+ var value;
2004
+ var found = false;
2005
+ this.forEach(function (x) {
2006
+ if (!found) {
2007
+ found = true;
2008
+ value = x;
2009
+ } else throw new Error("single:sequence contains more than one element.");
2010
+ });
2011
+
2012
+ return (!found) ? defaultValue : value;
2013
+ };
2014
+
2015
+ Enumerable.prototype.skip = function (count) {
2016
+ var source = this;
2017
+
2018
+ return new Enumerable(function () {
2019
+ var enumerator;
2020
+ var index = 0;
2021
+
2022
+ return new IEnumerator(
2023
+ function () {
2024
+ enumerator = source.getEnumerator();
2025
+ while (index++ < count && enumerator.moveNext()) { }
2026
+ },
2027
+ function () {
2028
+ return (enumerator.moveNext())
2029
+ ? this.yieldReturn(enumerator.current())
2030
+ : false;
2031
+ },
2032
+ function () { Utils.dispose(enumerator); });
2033
+ });
2034
+ };
2035
+
2036
+ // Overload:function(predicate<element>)
2037
+ // Overload:function(predicate<element,index>)
2038
+ Enumerable.prototype.skipWhile = function (predicate) {
2039
+ predicate = Utils.createLambda(predicate);
2040
+ var source = this;
2041
+
2042
+ return new Enumerable(function () {
2043
+ var enumerator;
2044
+ var index = 0;
2045
+ var isSkipEnd = false;
2046
+
2047
+ return new IEnumerator(
2048
+ function () { enumerator = source.getEnumerator(); },
2049
+ function () {
2050
+ while (!isSkipEnd) {
2051
+ if (enumerator.moveNext()) {
2052
+ if (!predicate(enumerator.current(), index++)) {
2053
+ isSkipEnd = true;
2054
+ return this.yieldReturn(enumerator.current());
2055
+ }
2056
+ continue;
2057
+ } else return false;
2058
+ }
2059
+
2060
+ return (enumerator.moveNext())
2061
+ ? this.yieldReturn(enumerator.current())
2062
+ : false;
2063
+
2064
+ },
2065
+ function () { Utils.dispose(enumerator); });
2066
+ });
2067
+ };
2068
+
2069
+ Enumerable.prototype.take = function (count) {
2070
+ var source = this;
2071
+
2072
+ return new Enumerable(function () {
2073
+ var enumerator;
2074
+ var index = 0;
2075
+
2076
+ return new IEnumerator(
2077
+ function () { enumerator = source.getEnumerator(); },
2078
+ function () {
2079
+ return (index++ < count && enumerator.moveNext())
2080
+ ? this.yieldReturn(enumerator.current())
2081
+ : false;
2082
+ },
2083
+ function () { Utils.dispose(enumerator); }
2084
+ );
2085
+ });
2086
+ };
2087
+
2088
+ // Overload:function(predicate<element>)
2089
+ // Overload:function(predicate<element,index>)
2090
+ Enumerable.prototype.takeWhile = function (predicate) {
2091
+ predicate = Utils.createLambda(predicate);
2092
+ var source = this;
2093
+
2094
+ return new Enumerable(function () {
2095
+ var enumerator;
2096
+ var index = 0;
2097
+
2098
+ return new IEnumerator(
2099
+ function () { enumerator = source.getEnumerator(); },
2100
+ function () {
2101
+ return (enumerator.moveNext() && predicate(enumerator.current(), index++))
2102
+ ? this.yieldReturn(enumerator.current())
2103
+ : false;
2104
+ },
2105
+ function () { Utils.dispose(enumerator); });
2106
+ });
2107
+ };
2108
+
2109
+ // Overload:function()
2110
+ // Overload:function(count)
2111
+ Enumerable.prototype.takeExceptLast = function (count) {
2112
+ if (count == null) count = 1;
2113
+ var source = this;
2114
+
2115
+ return new Enumerable(function () {
2116
+ if (count <= 0) return source.getEnumerator(); // do nothing
2117
+
2118
+ var enumerator;
2119
+ var q = [];
2120
+
2121
+ return new IEnumerator(
2122
+ function () { enumerator = source.getEnumerator(); },
2123
+ function () {
2124
+ while (enumerator.moveNext()) {
2125
+ if (q.length == count) {
2126
+ q.push(enumerator.current());
2127
+ return this.yieldReturn(q.shift());
2128
+ }
2129
+ q.push(enumerator.current());
2130
+ }
2131
+ return false;
2132
+ },
2133
+ function () { Utils.dispose(enumerator); });
2134
+ });
2135
+ };
2136
+
2137
+ Enumerable.prototype.takeFromLast = function (count) {
2138
+ if (count <= 0 || count == null) return Enumerable.empty();
2139
+ var source = this;
2140
+
2141
+ return new Enumerable(function () {
2142
+ var sourceEnumerator;
2143
+ var enumerator;
2144
+ var q = [];
2145
+
2146
+ return new IEnumerator(
2147
+ function () { sourceEnumerator = source.getEnumerator(); },
2148
+ function () {
2149
+ while (sourceEnumerator.moveNext()) {
2150
+ if (q.length == count) q.shift();
2151
+ q.push(sourceEnumerator.current());
2152
+ }
2153
+ if (enumerator == null) {
2154
+ enumerator = Enumerable.from(q).getEnumerator();
2155
+ }
2156
+ return (enumerator.moveNext())
2157
+ ? this.yieldReturn(enumerator.current())
2158
+ : false;
2159
+ },
2160
+ function () { Utils.dispose(enumerator); });
2161
+ });
2162
+ };
2163
+
2164
+ // Overload:function(item)
2165
+ // Overload:function(predicate)
2166
+ Enumerable.prototype.indexOf = function (item) {
2167
+ var found = null;
2168
+
2169
+ // item as predicate
2170
+ if (typeof (item) === Types.Function) {
2171
+ this.forEach(function (x, i) {
2172
+ if (item(x, i)) {
2173
+ found = i;
2174
+ return false;
2175
+ }
2176
+ });
2177
+ }
2178
+ else {
2179
+ this.forEach(function (x, i) {
2180
+ if (x === item) {
2181
+ found = i;
2182
+ return false;
2183
+ }
2184
+ });
2185
+ }
2186
+
2187
+ return (found !== null) ? found : -1;
2188
+ };
2189
+
2190
+ // Overload:function(item)
2191
+ // Overload:function(predicate)
2192
+ Enumerable.prototype.lastIndexOf = function (item) {
2193
+ var result = -1;
2194
+
2195
+ // item as predicate
2196
+ if (typeof (item) === Types.Function) {
2197
+ this.forEach(function (x, i) {
2198
+ if (item(x, i)) result = i;
2199
+ });
2200
+ }
2201
+ else {
2202
+ this.forEach(function (x, i) {
2203
+ if (x === item) result = i;
2204
+ });
2205
+ }
2206
+
2207
+ return result;
2208
+ };
2209
+
2210
+ ///////////////////
2211
+ // Convert Methods
2212
+
2213
+ Enumerable.prototype.cast = function () {
2214
+ return this;
2215
+ };
2216
+
2217
+ Enumerable.prototype.asEnumerable = function () {
2218
+ return Enumerable.from(this);
2219
+ };
2220
+
2221
+ Enumerable.prototype.toArray = function () {
2222
+ var array = [];
2223
+ this.forEach(function (x) { array.push(x); });
2224
+ return array;
2225
+ };
2226
+
2227
+ // Overload:function(keySelector)
2228
+ // Overload:function(keySelector, elementSelector)
2229
+ // Overload:function(keySelector, elementSelector, compareSelector)
2230
+ Enumerable.prototype.toLookup = function (keySelector, elementSelector, compareSelector) {
2231
+ keySelector = Utils.createLambda(keySelector);
2232
+ elementSelector = Utils.createLambda(elementSelector);
2233
+ compareSelector = Utils.createLambda(compareSelector);
2234
+
2235
+ var dict = new Dictionary(compareSelector);
2236
+ this.forEach(function (x) {
2237
+ var key = keySelector(x);
2238
+ var element = elementSelector(x);
2239
+
2240
+ var array = dict.get(key);
2241
+ if (array !== undefined) array.push(element);
2242
+ else dict.add(key, [element]);
2243
+ });
2244
+ return new Lookup(dict);
2245
+ };
2246
+
2247
+ Enumerable.prototype.toObject = function (keySelector, elementSelector) {
2248
+ keySelector = Utils.createLambda(keySelector);
2249
+ elementSelector = Utils.createLambda(elementSelector);
2250
+
2251
+ var obj = {};
2252
+ this.forEach(function (x) {
2253
+ obj[keySelector(x)] = elementSelector(x);
2254
+ });
2255
+ return obj;
2256
+ };
2257
+
2258
+ // Overload:function(keySelector, elementSelector)
2259
+ // Overload:function(keySelector, elementSelector, compareSelector)
2260
+ Enumerable.prototype.toDictionary = function (keySelector, elementSelector, compareSelector) {
2261
+ keySelector = Utils.createLambda(keySelector);
2262
+ elementSelector = Utils.createLambda(elementSelector);
2263
+ compareSelector = Utils.createLambda(compareSelector);
2264
+
2265
+ var dict = new Dictionary(compareSelector);
2266
+ this.forEach(function (x) {
2267
+ dict.add(keySelector(x), elementSelector(x));
2268
+ });
2269
+ return dict;
2270
+ };
2271
+
2272
+ // Overload:function()
2273
+ // Overload:function(replacer)
2274
+ // Overload:function(replacer, space)
2275
+ Enumerable.prototype.toJSONString = function (replacer, space) {
2276
+ if (typeof JSON === Types.Undefined || JSON.stringify == null) {
2277
+ throw new Error("toJSONString can't find JSON.stringify. This works native JSON support Browser or include json2.js");
2278
+ }
2279
+ return JSON.stringify(this.toArray(), replacer, space);
2280
+ };
2281
+
2282
+ // Overload:function()
2283
+ // Overload:function(separator)
2284
+ // Overload:function(separator,selector)
2285
+ Enumerable.prototype.toJoinedString = function (separator, selector) {
2286
+ if (separator == null) separator = "";
2287
+ if (selector == null) selector = Functions.Identity;
2288
+
2289
+ return this.select(selector).toArray().join(separator);
2290
+ };
2291
+
2292
+ //////////////////
2293
+ // Action Methods
2294
+
2295
+ // Overload:function(action<element>)
2296
+ // Overload:function(action<element,index>)
2297
+ Enumerable.prototype.doAction = function (action) {
2298
+ var source = this;
2299
+ action = Utils.createLambda(action);
2300
+
2301
+ return new Enumerable(function () {
2302
+ var enumerator;
2303
+ var index = 0;
2304
+
2305
+ return new IEnumerator(
2306
+ function () { enumerator = source.getEnumerator(); },
2307
+ function () {
2308
+ if (enumerator.moveNext()) {
2309
+ action(enumerator.current(), index++);
2310
+ return this.yieldReturn(enumerator.current());
2311
+ }
2312
+ return false;
2313
+ },
2314
+ function () { Utils.dispose(enumerator); });
2315
+ });
2316
+ };
2317
+
2318
+ // Overload:function(action<element>)
2319
+ // Overload:function(action<element,index>)
2320
+ // Overload:function(func<element,bool>)
2321
+ // Overload:function(func<element,index,bool>)
2322
+ Enumerable.prototype.forEach = function (action) {
2323
+ action = Utils.createLambda(action);
2324
+
2325
+ var index = 0;
2326
+ var enumerator = this.getEnumerator();
2327
+ try {
2328
+ while (enumerator.moveNext()) {
2329
+ if (action(enumerator.current(), index++) === false) break;
2330
+ }
2331
+ } finally {
2332
+ Utils.dispose(enumerator);
2333
+ }
2334
+ };
2335
+
2336
+ Enumerable.prototype.force = function () {
2337
+ var enumerator = this.getEnumerator();
2338
+
2339
+ try {
2340
+ while (enumerator.moveNext()) { }
2341
+ }
2342
+ finally {
2343
+ Utils.dispose(enumerator);
2344
+ }
2345
+ };
2346
+
2347
+ //////////////////////
2348
+ // Functional Methods
2349
+
2350
+ Enumerable.prototype.letBind = function (func) {
2351
+ func = Utils.createLambda(func);
2352
+ var source = this;
2353
+
2354
+ return new Enumerable(function () {
2355
+ var enumerator;
2356
+
2357
+ return new IEnumerator(
2358
+ function () {
2359
+ enumerator = Enumerable.from(func(source)).getEnumerator();
2360
+ },
2361
+ function () {
2362
+ return (enumerator.moveNext())
2363
+ ? this.yieldReturn(enumerator.current())
2364
+ : false;
2365
+ },
2366
+ function () { Utils.dispose(enumerator); });
2367
+ });
2368
+ };
2369
+
2370
+ Enumerable.prototype.share = function () {
2371
+ var source = this;
2372
+ var sharedEnumerator;
2373
+ var disposed = false;
2374
+
2375
+ return new DisposableEnumerable(function () {
2376
+ return new IEnumerator(
2377
+ function () {
2378
+ if (sharedEnumerator == null) {
2379
+ sharedEnumerator = source.getEnumerator();
2380
+ }
2381
+ },
2382
+ function () {
2383
+ if (disposed) throw new Error("enumerator is disposed");
2384
+
2385
+ return (sharedEnumerator.moveNext())
2386
+ ? this.yieldReturn(sharedEnumerator.current())
2387
+ : false;
2388
+ },
2389
+ Functions.Blank
2390
+ );
2391
+ }, function () {
2392
+ disposed = true;
2393
+ Utils.dispose(sharedEnumerator);
2394
+ });
2395
+ };
2396
+
2397
+ Enumerable.prototype.memoize = function () {
2398
+ var source = this;
2399
+ var cache;
2400
+ var enumerator;
2401
+ var disposed = false;
2402
+
2403
+ return new DisposableEnumerable(function () {
2404
+ var index = -1;
2405
+
2406
+ return new IEnumerator(
2407
+ function () {
2408
+ if (enumerator == null) {
2409
+ enumerator = source.getEnumerator();
2410
+ cache = [];
2411
+ }
2412
+ },
2413
+ function () {
2414
+ if (disposed) throw new Error("enumerator is disposed");
2415
+
2416
+ index++;
2417
+ if (cache.length <= index) {
2418
+ return (enumerator.moveNext())
2419
+ ? this.yieldReturn(cache[index] = enumerator.current())
2420
+ : false;
2421
+ }
2422
+
2423
+ return this.yieldReturn(cache[index]);
2424
+ },
2425
+ Functions.Blank
2426
+ );
2427
+ }, function () {
2428
+ disposed = true;
2429
+ Utils.dispose(enumerator);
2430
+ cache = null;
2431
+ });
2432
+ };
2433
+
2434
+ // Iterator support (ES6 for..of)
2435
+ if (Utils.hasNativeIteratorSupport()) {
2436
+ Enumerable.prototype[Symbol.iterator] = function () {
2437
+ return {
2438
+ enumerator: this.getEnumerator(),
2439
+ next: function () {
2440
+ if (this.enumerator.moveNext()) {
2441
+ return {
2442
+ done: false,
2443
+ value: this.enumerator.current()
2444
+ };
2445
+ } else {
2446
+ return { done: true };
2447
+ }
2448
+ }
2449
+ };
2450
+ };
2451
+ }
2452
+
2453
+ //////////////////////////
2454
+ // Error Handling Methods
2455
+
2456
+ Enumerable.prototype.catchError = function (handler) {
2457
+ handler = Utils.createLambda(handler);
2458
+ var source = this;
2459
+
2460
+ return new Enumerable(function () {
2461
+ var enumerator;
2462
+
2463
+ return new IEnumerator(
2464
+ function () { enumerator = source.getEnumerator(); },
2465
+ function () {
2466
+ try {
2467
+ return (enumerator.moveNext())
2468
+ ? this.yieldReturn(enumerator.current())
2469
+ : false;
2470
+ } catch (e) {
2471
+ handler(e);
2472
+ return false;
2473
+ }
2474
+ },
2475
+ function () { Utils.dispose(enumerator); });
2476
+ });
2477
+ };
2478
+
2479
+ Enumerable.prototype.finallyAction = function (finallyAction) {
2480
+ finallyAction = Utils.createLambda(finallyAction);
2481
+ var source = this;
2482
+
2483
+ return new Enumerable(function () {
2484
+ var enumerator;
2485
+
2486
+ return new IEnumerator(
2487
+ function () { enumerator = source.getEnumerator(); },
2488
+ function () {
2489
+ return (enumerator.moveNext())
2490
+ ? this.yieldReturn(enumerator.current())
2491
+ : false;
2492
+ },
2493
+ function () {
2494
+ try {
2495
+ Utils.dispose(enumerator);
2496
+ } finally {
2497
+ finallyAction();
2498
+ }
2499
+ });
2500
+ });
2501
+ };
2502
+
2503
+ /////////////////
2504
+ // Debug Methods
2505
+
2506
+ // Overload:function()
2507
+ // Overload:function(selector)
2508
+ Enumerable.prototype.log = function (selector) {
2509
+ selector = Utils.createLambda(selector);
2510
+
2511
+ return this.doAction(function (item) {
2512
+ if (typeof console !== Types.Undefined) {
2513
+ console.log(selector(item));
2514
+ }
2515
+ });
2516
+ };
2517
+
2518
+ // Overload:function()
2519
+ // Overload:function(message)
2520
+ // Overload:function(message,selector)
2521
+ Enumerable.prototype.trace = function (message, selector) {
2522
+ if (message == null) message = "Trace";
2523
+ selector = Utils.createLambda(selector);
2524
+
2525
+ return this.doAction(function (item) {
2526
+ if (typeof console !== Types.Undefined) {
2527
+ console.log(message, selector(item));
2528
+ }
2529
+ });
2530
+ };
2531
+
2532
+ ///////////
2533
+ // Private
2534
+
2535
+ var OrderedEnumerable = function (source, keySelector, comparer, descending, parent) {
2536
+ this.source = source;
2537
+ this.keySelector = Utils.createLambda(keySelector);
2538
+ this.descending = descending;
2539
+ this.parent = parent;
2540
+
2541
+ if (comparer)
2542
+ this.comparer = Utils.createLambda(comparer);
2543
+ };
2544
+ OrderedEnumerable.prototype = new Enumerable();
2545
+
2546
+ OrderedEnumerable.prototype.createOrderedEnumerable = function (keySelector, comparer, descending) {
2547
+ return new OrderedEnumerable(this.source, keySelector, comparer, descending, this);
2548
+ };
2549
+
2550
+ OrderedEnumerable.prototype.thenBy = function (keySelector, comparer) {
2551
+ return this.createOrderedEnumerable(keySelector, comparer, false);
2552
+ };
2553
+
2554
+ OrderedEnumerable.prototype.thenByDescending = function (keySelector, comparer) {
2555
+ return this.createOrderedEnumerable(keySelector, comparer, true);
2556
+ };
2557
+
2558
+ OrderedEnumerable.prototype.getEnumerator = function () {
2559
+ var self = this;
2560
+ var buffer;
2561
+ var indexes;
2562
+ var index = 0;
2563
+
2564
+ return new IEnumerator(
2565
+ function () {
2566
+ buffer = [];
2567
+ indexes = [];
2568
+ self.source.forEach(function (item, index) {
2569
+ buffer.push(item);
2570
+ indexes.push(index);
2571
+ });
2572
+ var sortContext = SortContext.create(self, null);
2573
+ sortContext.GenerateKeys(buffer);
2574
+
2575
+ indexes.sort(function (a, b) { return sortContext.compare(a, b); });
2576
+ },
2577
+ function () {
2578
+ return (index < indexes.length)
2579
+ ? this.yieldReturn(buffer[indexes[index++]])
2580
+ : false;
2581
+ },
2582
+ Functions.Blank
2583
+ );
2584
+ };
2585
+
2586
+ var SortContext = function (keySelector, comparer, descending, child) {
2587
+ this.keySelector = keySelector;
2588
+ this.descending = descending;
2589
+ this.child = child;
2590
+ this.comparer = comparer;
2591
+ this.keys = null;
2592
+ };
2593
+
2594
+ SortContext.create = function (orderedEnumerable, currentContext) {
2595
+ var context = new SortContext(
2596
+ orderedEnumerable.keySelector, orderedEnumerable.comparer, orderedEnumerable.descending, currentContext
2597
+ );
2598
+
2599
+ if (orderedEnumerable.parent != null) return SortContext.create(orderedEnumerable.parent, context);
2600
+ return context;
2601
+ };
2602
+
2603
+ SortContext.prototype.GenerateKeys = function (source) {
2604
+ var len = source.length;
2605
+ var keySelector = this.keySelector;
2606
+ var keys = new Array(len);
2607
+ for (let i = 0; i < len; i++) keys[i] = keySelector(source[i]);
2608
+ this.keys = keys;
2609
+
2610
+ if (this.child != null) this.child.GenerateKeys(source);
2611
+ };
2612
+
2613
+ SortContext.prototype.compare = function (index1, index2) {
2614
+ var comparison = this.comparer ?
2615
+ this.comparer(this.keys[index1], this.keys[index2]) :
2616
+ Utils.compare(this.keys[index1], this.keys[index2]);
2617
+
2618
+ if (comparison == 0) {
2619
+ if (this.child != null) return this.child.compare(index1, index2);
2620
+ return Utils.compare(index1, index2);
2621
+ }
2622
+
2623
+ return (this.descending) ? -comparison : comparison;
2624
+ };
2625
+
2626
+ var DisposableEnumerable = function (getEnumerator, dispose) {
2627
+ this.dispose = dispose;
2628
+ Enumerable.call(this, getEnumerator);
2629
+ };
2630
+ DisposableEnumerable.prototype = new Enumerable();
2631
+
2632
+ var ArrayEnumerable = function (source) {
2633
+ this.getSource = function () { return source; };
2634
+ };
2635
+ ArrayEnumerable.prototype = new Enumerable();
2636
+
2637
+ ArrayEnumerable.prototype.any = function (predicate) {
2638
+ return (predicate == null)
2639
+ ? (this.getSource().length > 0)
2640
+ : Enumerable.prototype.any.apply(this, arguments);
2641
+ };
2642
+
2643
+ ArrayEnumerable.prototype.count = function (predicate) {
2644
+ return (predicate == null)
2645
+ ? this.getSource().length
2646
+ : Enumerable.prototype.count.apply(this, arguments);
2647
+ };
2648
+
2649
+ ArrayEnumerable.prototype.elementAt = function (index) {
2650
+ var source = this.getSource();
2651
+ return (0 <= index && index < source.length)
2652
+ ? source[index]
2653
+ : Enumerable.prototype.elementAt.apply(this, arguments);
2654
+ };
2655
+
2656
+ ArrayEnumerable.prototype.elementAtOrDefault = function (index, defaultValue) {
2657
+ if (defaultValue === undefined) defaultValue = null;
2658
+ var source = this.getSource();
2659
+ return (0 <= index && index < source.length)
2660
+ ? source[index]
2661
+ : defaultValue;
2662
+ };
2663
+
2664
+ ArrayEnumerable.prototype.first = function (predicate) {
2665
+ var source = this.getSource();
2666
+ return (predicate == null && source.length > 0)
2667
+ ? source[0]
2668
+ : Enumerable.prototype.first.apply(this, arguments);
2669
+ };
2670
+
2671
+ ArrayEnumerable.prototype.firstOrDefault = function (predicate, defaultValue) {
2672
+ if (predicate !== undefined) {
2673
+ return Enumerable.prototype.firstOrDefault.apply(this, arguments);
2674
+ }
2675
+ defaultValue = predicate;
2676
+
2677
+ var source = this.getSource();
2678
+ return source.length > 0 ? source[0] : defaultValue;
2679
+ };
2680
+
2681
+ ArrayEnumerable.prototype.last = function (predicate) {
2682
+ var source = this.getSource();
2683
+ return (predicate == null && source.length > 0)
2684
+ ? source[source.length - 1]
2685
+ : Enumerable.prototype.last.apply(this, arguments);
2686
+ };
2687
+
2688
+ ArrayEnumerable.prototype.lastOrDefault = function (predicate, defaultValue) {
2689
+ if (predicate !== undefined) {
2690
+ return Enumerable.prototype.lastOrDefault.apply(this, arguments);
2691
+ }
2692
+ defaultValue = predicate;
2693
+
2694
+ var source = this.getSource();
2695
+ return source.length > 0 ? source[source.length - 1] : defaultValue;
2696
+ };
2697
+
2698
+ ArrayEnumerable.prototype.skip = function (count) {
2699
+ var source = this.getSource();
2700
+
2701
+ return new Enumerable(function () {
2702
+ var index;
2703
+
2704
+ return new IEnumerator(
2705
+ function () { index = (count < 0) ? 0 : count; },
2706
+ function () {
2707
+ return (index < source.length)
2708
+ ? this.yieldReturn(source[index++])
2709
+ : false;
2710
+ },
2711
+ Functions.Blank);
2712
+ });
2713
+ };
2714
+
2715
+ ArrayEnumerable.prototype.takeExceptLast = function (count) {
2716
+ if (count == null) count = 1;
2717
+ return this.take(this.getSource().length - count);
2718
+ };
2719
+
2720
+ ArrayEnumerable.prototype.takeFromLast = function (count) {
2721
+ return this.skip(this.getSource().length - count);
2722
+ };
2723
+
2724
+ ArrayEnumerable.prototype.reverse = function () {
2725
+ var source = this.getSource();
2726
+
2727
+ return new Enumerable(function () {
2728
+ var index;
2729
+
2730
+ return new IEnumerator(
2731
+ function () {
2732
+ index = source.length;
2733
+ },
2734
+ function () {
2735
+ return (index > 0)
2736
+ ? this.yieldReturn(source[--index])
2737
+ : false;
2738
+ },
2739
+ Functions.Blank);
2740
+ });
2741
+ };
2742
+
2743
+ ArrayEnumerable.prototype.sequenceEqual = function (second, compareSelector) {
2744
+ if ((second instanceof ArrayEnumerable || second instanceof Array)
2745
+ && compareSelector == null
2746
+ && Enumerable.from(second).count() != this.count()) {
2747
+ return false;
2748
+ }
2749
+
2750
+ return Enumerable.prototype.sequenceEqual.apply(this, arguments);
2751
+ };
2752
+
2753
+ ArrayEnumerable.prototype.toJoinedString = function (separator, selector) {
2754
+ var source = this.getSource();
2755
+ if (selector != null || !(source instanceof Array)) {
2756
+ return Enumerable.prototype.toJoinedString.apply(this, arguments);
2757
+ }
2758
+
2759
+ if (separator == null) separator = "";
2760
+ return source.join(separator);
2761
+ };
2762
+
2763
+ ArrayEnumerable.prototype.getEnumerator = function () {
2764
+ var source = this.getSource();
2765
+ var index = -1;
2766
+
2767
+ // fast and simple enumerator
2768
+ return {
2769
+ current: function () { return source[index]; },
2770
+ moveNext: function () {
2771
+ return ++index < source.length;
2772
+ },
2773
+ dispose: Functions.Blank
2774
+ };
2775
+ };
2776
+
2777
+ // optimization for multiple where and multiple select and whereselect
2778
+
2779
+ var WhereEnumerable = function (source, predicate) {
2780
+ this.prevSource = source;
2781
+ this.prevPredicate = predicate; // predicate.length always <= 1
2782
+ };
2783
+ WhereEnumerable.prototype = new Enumerable();
2784
+
2785
+ WhereEnumerable.prototype.where = function (predicate) {
2786
+ predicate = Utils.createLambda(predicate);
2787
+
2788
+ if (predicate.length <= 1) {
2789
+ const prevPredicate = this.prevPredicate;
2790
+ const composedPredicate = function (x) { return prevPredicate(x) && predicate(x); };
2791
+ return new WhereEnumerable(this.prevSource, composedPredicate);
2792
+ }
2793
+ else {
2794
+ // if predicate use index, can't compose
2795
+ return Enumerable.prototype.where.call(this, predicate);
2796
+ }
2797
+ };
2798
+
2799
+ WhereEnumerable.prototype.select = function (selector) {
2800
+ selector = Utils.createLambda(selector);
2801
+
2802
+ return (selector.length <= 1)
2803
+ ? new WhereSelectEnumerable(this.prevSource, this.prevPredicate, selector)
2804
+ : Enumerable.prototype.select.call(this, selector);
2805
+ };
2806
+
2807
+ WhereEnumerable.prototype.getEnumerator = function () {
2808
+ var predicate = this.prevPredicate;
2809
+ var source = this.prevSource;
2810
+ var enumerator;
2811
+
2812
+ return new IEnumerator(
2813
+ function () { enumerator = source.getEnumerator(); },
2814
+ function () {
2815
+ while (enumerator.moveNext()) {
2816
+ if (predicate(enumerator.current())) {
2817
+ return this.yieldReturn(enumerator.current());
2818
+ }
2819
+ }
2820
+ return false;
2821
+ },
2822
+ function () { Utils.dispose(enumerator); });
2823
+ };
2824
+
2825
+ var WhereSelectEnumerable = function (source, predicate, selector) {
2826
+ this.prevSource = source;
2827
+ this.prevPredicate = predicate; // predicate.length always <= 1 or null
2828
+ this.prevSelector = selector; // selector.length always <= 1
2829
+ };
2830
+ WhereSelectEnumerable.prototype = new Enumerable();
2831
+
2832
+ WhereSelectEnumerable.prototype.where = function (predicate) {
2833
+ predicate = Utils.createLambda(predicate);
2834
+
2835
+ return (predicate.length <= 1)
2836
+ ? new WhereEnumerable(this, predicate)
2837
+ : Enumerable.prototype.where.call(this, predicate);
2838
+ };
2839
+
2840
+ WhereSelectEnumerable.prototype.select = function (selector) {
2841
+ selector = Utils.createLambda(selector);
2842
+
2843
+ if (selector.length <= 1) {
2844
+ const prevSelector = this.prevSelector;
2845
+ const composedSelector = function (x) { return selector(prevSelector(x)); };
2846
+ return new WhereSelectEnumerable(this.prevSource, this.prevPredicate, composedSelector);
2847
+ }
2848
+ else {
2849
+ // if selector uses index, can't compose
2850
+ return Enumerable.prototype.select.call(this, selector);
2851
+ }
2852
+ };
2853
+
2854
+ WhereSelectEnumerable.prototype.getEnumerator = function () {
2855
+ var predicate = this.prevPredicate;
2856
+ var selector = this.prevSelector;
2857
+ var source = this.prevSource;
2858
+ var enumerator;
2859
+
2860
+ return new IEnumerator(
2861
+ function () { enumerator = source.getEnumerator(); },
2862
+ function () {
2863
+ while (enumerator.moveNext()) {
2864
+ if (predicate == null || predicate(enumerator.current())) {
2865
+ return this.yieldReturn(selector(enumerator.current()));
2866
+ }
2867
+ }
2868
+ return false;
2869
+ },
2870
+ function () { Utils.dispose(enumerator); });
2871
+ };
2872
+
2873
+ ///////////////
2874
+ // Collections
2875
+
2876
+ var Dictionary = (function () {
2877
+ // static utility methods
2878
+ var callHasOwnProperty = function (target, key) {
2879
+ return Object.prototype.hasOwnProperty.call(target, key);
2880
+ };
2881
+
2882
+ var computeHashCode = function (obj) {
2883
+ if (obj === null) return "null";
2884
+ if (obj === undefined) return "undefined";
2885
+
2886
+ return (typeof obj.toString === Types.Function)
2887
+ ? obj.toString()
2888
+ : Object.prototype.toString.call(obj);
2889
+ };
2890
+
2891
+ // LinkedList for Dictionary
2892
+ var HashEntry = function (key, value) {
2893
+ this.key = key;
2894
+ this.value = value;
2895
+ this.prev = null;
2896
+ this.next = null;
2897
+ };
2898
+
2899
+ var EntryList = function () {
2900
+ this.first = null;
2901
+ this.last = null;
2902
+ };
2903
+ EntryList.prototype =
2904
+ {
2905
+ addLast: function (entry) {
2906
+ if (this.last != null) {
2907
+ this.last.next = entry;
2908
+ entry.prev = this.last;
2909
+ this.last = entry;
2910
+ } else this.first = this.last = entry;
2911
+ },
2912
+
2913
+ replace: function (entry, newEntry) {
2914
+ if (entry.prev != null) {
2915
+ entry.prev.next = newEntry;
2916
+ newEntry.prev = entry.prev;
2917
+ } else this.first = newEntry;
2918
+
2919
+ if (entry.next != null) {
2920
+ entry.next.prev = newEntry;
2921
+ newEntry.next = entry.next;
2922
+ } else this.last = newEntry;
2923
+
2924
+ },
2925
+
2926
+ remove: function (entry) {
2927
+ if (entry.prev != null) entry.prev.next = entry.next;
2928
+ else this.first = entry.next;
2929
+
2930
+ if (entry.next != null) entry.next.prev = entry.prev;
2931
+ else this.last = entry.prev;
2932
+ }
2933
+ };
2934
+
2935
+ // Overload:function()
2936
+ // Overload:function(compareSelector)
2937
+ var Dictionary = function (compareSelector) {
2938
+ this.countField = 0;
2939
+ this.entryList = new EntryList();
2940
+ this.buckets = {}; // as Dictionary<string,List<object>>
2941
+ this.compareSelector = (compareSelector == null) ? Functions.Identity : compareSelector;
2942
+ };
2943
+ Dictionary.prototype =
2944
+ {
2945
+ add: function (key, value) {
2946
+ var compareKey = this.compareSelector(key);
2947
+ var hash = computeHashCode(compareKey);
2948
+ var entry = new HashEntry(key, value);
2949
+ if (callHasOwnProperty(this.buckets, hash)) {
2950
+ const array = this.buckets[hash];
2951
+ for (let i = 0; i < array.length; i++) {
2952
+ if (this.compareSelector(array[i].key) === compareKey) {
2953
+ this.entryList.replace(array[i], entry);
2954
+ array[i] = entry;
2955
+ return;
2956
+ }
2957
+ }
2958
+ array.push(entry);
2959
+ } else {
2960
+ this.buckets[hash] = [entry];
2961
+ }
2962
+ this.countField++;
2963
+ this.entryList.addLast(entry);
2964
+ },
2965
+
2966
+ get: function (key) {
2967
+ var compareKey = this.compareSelector(key);
2968
+ var hash = computeHashCode(compareKey);
2969
+ if (!callHasOwnProperty(this.buckets, hash)) return undefined;
2970
+
2971
+ var array = this.buckets[hash];
2972
+ for (let i = 0; i < array.length; i++) {
2973
+ const entry = array[i];
2974
+ if (this.compareSelector(entry.key) === compareKey) return entry.value;
2975
+ }
2976
+ return undefined;
2977
+ },
2978
+
2979
+ set: function (key, value) {
2980
+ var compareKey = this.compareSelector(key);
2981
+ var hash = computeHashCode(compareKey);
2982
+ if (callHasOwnProperty(this.buckets, hash)) {
2983
+ const array = this.buckets[hash];
2984
+ for (let i = 0; i < array.length; i++) {
2985
+ if (this.compareSelector(array[i].key) === compareKey) {
2986
+ const newEntry = new HashEntry(key, value);
2987
+ this.entryList.replace(array[i], newEntry);
2988
+ array[i] = newEntry;
2989
+ return true;
2990
+ }
2991
+ }
2992
+ }
2993
+ return false;
2994
+ },
2995
+
2996
+ contains: function (key) {
2997
+ var compareKey = this.compareSelector(key);
2998
+ var hash = computeHashCode(compareKey);
2999
+ if (!callHasOwnProperty(this.buckets, hash)) return false;
3000
+
3001
+ var array = this.buckets[hash];
3002
+ for (let i = 0; i < array.length; i++) {
3003
+ if (this.compareSelector(array[i].key) === compareKey) return true;
3004
+ }
3005
+ return false;
3006
+ },
3007
+
3008
+ clear: function () {
3009
+ this.countField = 0;
3010
+ this.buckets = {};
3011
+ this.entryList = new EntryList();
3012
+ },
3013
+
3014
+ remove: function (key) {
3015
+ var compareKey = this.compareSelector(key);
3016
+ var hash = computeHashCode(compareKey);
3017
+ if (!callHasOwnProperty(this.buckets, hash)) return;
3018
+
3019
+ var array = this.buckets[hash];
3020
+ for (let i = 0; i < array.length; i++) {
3021
+ if (this.compareSelector(array[i].key) === compareKey) {
3022
+ this.entryList.remove(array[i]);
3023
+ array.splice(i, 1);
3024
+ if (array.length == 0) delete this.buckets[hash];
3025
+ this.countField--;
3026
+ return;
3027
+ }
3028
+ }
3029
+ },
3030
+
3031
+ count: function () {
3032
+ return this.countField;
3033
+ },
3034
+
3035
+ toEnumerable: function () {
3036
+ var self = this;
3037
+ return new Enumerable(function () {
3038
+ var currentEntry;
3039
+
3040
+ return new IEnumerator(
3041
+ function () { currentEntry = self.entryList.first; },
3042
+ function () {
3043
+ if (currentEntry != null) {
3044
+ const result = { key: currentEntry.key, value: currentEntry.value };
3045
+ currentEntry = currentEntry.next;
3046
+ return this.yieldReturn(result);
3047
+ }
3048
+ return false;
3049
+ },
3050
+ Functions.Blank);
3051
+ });
3052
+ }
3053
+ };
3054
+
3055
+ return Dictionary;
3056
+ })();
3057
+
3058
+ // dictionary = Dictionary<TKey, TValue[]>
3059
+ var Lookup = function (dictionary) {
3060
+ this.count = function () {
3061
+ return dictionary.count();
3062
+ };
3063
+ this.get = function (key) {
3064
+ return Enumerable.from(dictionary.get(key));
3065
+ };
3066
+ this.contains = function (key) {
3067
+ return dictionary.contains(key);
3068
+ };
3069
+ this.toEnumerable = function () {
3070
+ return dictionary.toEnumerable().select(function (kvp) {
3071
+ return new Grouping(kvp.key, kvp.value);
3072
+ });
3073
+ };
3074
+ };
3075
+
3076
+ var Grouping = function (groupKey, elements) {
3077
+ this.key = function () {
3078
+ return groupKey;
3079
+ };
3080
+ ArrayEnumerable.call(this, elements);
3081
+ };
3082
+ Grouping.prototype = new ArrayEnumerable();
3083
+
3084
+ export default Enumerable;
3085
+ export { Enumerable };