iterator.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. export var Iterable;
  6. (function (Iterable) {
  7. function is(thing) {
  8. return thing && typeof thing === 'object' && typeof thing[Symbol.iterator] === 'function';
  9. }
  10. Iterable.is = is;
  11. const _empty = Object.freeze([]);
  12. function empty() {
  13. return _empty;
  14. }
  15. Iterable.empty = empty;
  16. function* single(element) {
  17. yield element;
  18. }
  19. Iterable.single = single;
  20. function wrap(iterableOrElement) {
  21. if (is(iterableOrElement)) {
  22. return iterableOrElement;
  23. }
  24. else {
  25. return single(iterableOrElement);
  26. }
  27. }
  28. Iterable.wrap = wrap;
  29. function from(iterable) {
  30. return iterable || _empty;
  31. }
  32. Iterable.from = from;
  33. function isEmpty(iterable) {
  34. return !iterable || iterable[Symbol.iterator]().next().done === true;
  35. }
  36. Iterable.isEmpty = isEmpty;
  37. function first(iterable) {
  38. return iterable[Symbol.iterator]().next().value;
  39. }
  40. Iterable.first = first;
  41. function some(iterable, predicate) {
  42. for (const element of iterable) {
  43. if (predicate(element)) {
  44. return true;
  45. }
  46. }
  47. return false;
  48. }
  49. Iterable.some = some;
  50. function find(iterable, predicate) {
  51. for (const element of iterable) {
  52. if (predicate(element)) {
  53. return element;
  54. }
  55. }
  56. return undefined;
  57. }
  58. Iterable.find = find;
  59. function* filter(iterable, predicate) {
  60. for (const element of iterable) {
  61. if (predicate(element)) {
  62. yield element;
  63. }
  64. }
  65. }
  66. Iterable.filter = filter;
  67. function* map(iterable, fn) {
  68. let index = 0;
  69. for (const element of iterable) {
  70. yield fn(element, index++);
  71. }
  72. }
  73. Iterable.map = map;
  74. function* concat(...iterables) {
  75. for (const iterable of iterables) {
  76. for (const element of iterable) {
  77. yield element;
  78. }
  79. }
  80. }
  81. Iterable.concat = concat;
  82. function reduce(iterable, reducer, initialValue) {
  83. let value = initialValue;
  84. for (const element of iterable) {
  85. value = reducer(value, element);
  86. }
  87. return value;
  88. }
  89. Iterable.reduce = reduce;
  90. /**
  91. * Returns an iterable slice of the array, with the same semantics as `array.slice()`.
  92. */
  93. function* slice(arr, from, to = arr.length) {
  94. if (from < 0) {
  95. from += arr.length;
  96. }
  97. if (to < 0) {
  98. to += arr.length;
  99. }
  100. else if (to > arr.length) {
  101. to = arr.length;
  102. }
  103. for (; from < to; from++) {
  104. yield arr[from];
  105. }
  106. }
  107. Iterable.slice = slice;
  108. /**
  109. * Consumes `atMost` elements from iterable and returns the consumed elements,
  110. * and an iterable for the rest of the elements.
  111. */
  112. function consume(iterable, atMost = Number.POSITIVE_INFINITY) {
  113. const consumed = [];
  114. if (atMost === 0) {
  115. return [consumed, iterable];
  116. }
  117. const iterator = iterable[Symbol.iterator]();
  118. for (let i = 0; i < atMost; i++) {
  119. const next = iterator.next();
  120. if (next.done) {
  121. return [consumed, Iterable.empty()];
  122. }
  123. consumed.push(next.value);
  124. }
  125. return [consumed, { [Symbol.iterator]() { return iterator; } }];
  126. }
  127. Iterable.consume = consume;
  128. })(Iterable || (Iterable = {}));