iterable-linq-utility 0.10.0 → 0.12.0

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/index.d.cts CHANGED
@@ -317,12 +317,34 @@ declare function entries<T>(iterable: Iterable<T>): Iterable<[number, T]>;
317
317
  */
318
318
  declare function every<T>(iterable: Iterable<T>, predicate: Predicate<T>): boolean;
319
319
 
320
+ /**
321
+ * Lazily yields the distinct values of `iterable` that are not in `other`, in the order of `iterable`.
322
+ * Before the first value it reads the whole `other` into a `Set`, so `other` must be finite; each run reads it again.
323
+ * Values, or the keys returned by `keySelector`, are compared with `SameValueZero`, like `Set`: for each key the first value of `iterable` is yielded.
324
+ * If `keySelector` throws, or `other` throws, the sources are closed and the error propagates.
325
+ * @operation `Transformation`
326
+ * @param iterable - the source `Iterable`
327
+ * @param other - the `Iterable` whose values, or keys, are left out
328
+ * @param keySelector - called with every value of `iterable` and of `other`, and its index in its own source; omitted or `undefined` compares the values
329
+ * @returns a lazy, re-runnable `Iterable` of the distinct values of `iterable` that are not in `other`
330
+ * @throws Error if `iterable` or `other` is missing or does not implement `[Symbol.iterator]`, or if a provided `keySelector` is not a function
331
+ * @example
332
+ * ```ts
333
+ * Array.from(Functions.except([1, 2, 2, 3], [3, 4])); // [1, 2]
334
+ * Array.from(Functions.except([{ id: 1 }, { id: 2 }], [{ id: 2 }], v => v.id)); // [{ id: 1 }]
335
+ * ```
336
+ * @since 0.12.0
337
+ */
338
+ declare function except<T, K>(iterable: Iterable<T>, other: Iterable<T>, keySelector?: Mapper<T, K>): Iterable<T>;
339
+
320
340
  /**
321
341
  * Adds a method to every chain, including the chains created before the call.
322
- * Declare the method first by augmenting `IIterableLinq`, then register it once, at application start-up.
323
- * @param name - the method name; it must not exist yet (library methods, earlier extensions, `Object.prototype` members)
342
+ * Declare the method first by augmenting `IIterableLinq`, then register it at application start-up.
343
+ * Registering a name added by an earlier `extend` again replaces its implementation, so a module that runs twice
344
+ * (hot module replacement, a test runner that re-imports it) does not throw: the last registration wins.
345
+ * @param name - the method name; a new name or one added by an earlier `extend`, not a library method or an `Object.prototype` member
324
346
  * @param implementation - the method; `this` is the chain, typed `IIterableLinq<unknown>`
325
- * @throws Error if `name` already exists (use `override` to replace it), is empty, or `implementation` is not a function
347
+ * @throws Error if `name` is a library method (use `override` to replace it), an `Object.prototype` member or a name used by the chain instances, is empty, or `implementation` is not a function
326
348
  * @example
327
349
  * ```ts
328
350
  * declare module 'iterable-linq-utility' {
@@ -564,6 +586,47 @@ declare function forEachAsync<T>(iterable: Iterable<T>, action: AsyncAction<T>):
564
586
  */
565
587
  export declare function from<T>(iterable: Iterable<T>): IIterableLinq<T>;
566
588
 
589
+ /**
590
+ * Starts a chain over the properties of `object`: its entries, its keys, its values or its property descriptors.
591
+ * With the default options it yields what `Object.entries` returns: the own, enumerable, string keys.
592
+ * - `options.yield`: `'entries'` (default) `[key, value]`, `'keys'`, `'values'`, or `'descriptors'` `[key, descriptor, owner]` without calling the getters.
593
+ * - `options.inherited` also reads the prototype chain, up to `Object.prototype` excluded; a key is yielded once, from the nearest object that has it, like `for…in`.
594
+ * - `options.nonEnumerable` also reads the non-enumerable properties, `options.symbols` the symbol keys.
595
+ * - Each run of the chain reads the object again: the keys of an object when the iteration reaches it, a value when it is yielded.
596
+ * @param object - the object to read
597
+ * @param options - `yield`, `inherited`, `nonEnumerable` and `symbols`
598
+ * @returns a chain of the properties of `object`
599
+ * @throws Error if `object` is not an object or a function, `options` is not an object, `yield` is not one of its values, or a flag is not a boolean
600
+ * @example
601
+ * ```ts
602
+ * IterableLinq.fromObject({ a: 1, b: 2 }).collectToArray(); // [['a', 1], ['b', 2]]
603
+ * IterableLinq.fromObject({ a: 1, b: 2 }, { yield: 'keys' }).collectToArray(); // ['a', 'b']
604
+ * IterableLinq.fromObject({ a: 1, b: 2 }, { yield: 'values' }).collectToArray(); // [1, 2]
605
+ * ```
606
+ * @since 0.11.0
607
+ */
608
+ export declare function fromObject<O extends object, const Options extends IObjectOptions = IObjectDefaultOptions>(object: O, options?: Options): IIterableLinq<ObjectItem<O, Options>>;
609
+
610
+ /**
611
+ * Returns the properties of `object`: its entries, its keys, its values or its property descriptors.
612
+ * With the default options it yields what `Object.entries` returns: the own, enumerable, string keys.
613
+ * - `inherited` also reads the prototype chain, up to `Object.prototype` excluded; a key is yielded once, from the nearest object that has it, like `for…in`.
614
+ * - `nonEnumerable` also reads the non-enumerable properties, `symbols` the symbol keys.
615
+ * - The keys of an object are read when the iteration reaches it, a value when it is yielded: each run reads the object again.
616
+ * @operation `Transformation`
617
+ * @param object - the object to read
618
+ * @param options - `yield` (`'entries'`, `'keys'`, `'values'` or `'descriptors'`), `inherited`, `nonEnumerable` and `symbols`
619
+ * @returns a lazy, re-runnable `Iterable` of the properties of `object`
620
+ * @throws Error if `object` is not an object or a function, `options` is not an object, `yield` is not one of its values, or a flag is not a boolean
621
+ * @example
622
+ * ```ts
623
+ * Array.from(Functions.fromObject({ a: 1, b: 2 })); // [['a', 1], ['b', 2]]
624
+ * Array.from(Functions.fromObject({ a: 1, b: 2 }, { yield: 'keys' })); // ['a', 'b']
625
+ * ```
626
+ * @since 0.11.0
627
+ */
628
+ declare function fromObject_2<O extends object, const Options extends IObjectOptions = IObjectDefaultOptions>(object: O, options?: Options): Iterable<ObjectItem<O, Options>>;
629
+
567
630
  /**
568
631
  * Starts a chain of numbers from 0 up to, but not including, `end`.
569
632
  * - `options.step` is the distance between two values (default 1); its sign is ignored, the direction comes from the sign of `end`.
@@ -621,6 +684,7 @@ declare namespace Functions {
621
684
  empty_2 as empty,
622
685
  entries,
623
686
  every,
687
+ except,
624
688
  filter,
625
689
  find,
626
690
  findIndex,
@@ -630,8 +694,13 @@ declare namespace Functions {
630
694
  flatMap,
631
695
  forEach,
632
696
  forEachAsync,
697
+ fromObject_2 as fromObject,
698
+ groupBy,
699
+ groupJoin,
633
700
  includes,
634
701
  indexOf,
702
+ innerJoin,
703
+ intersect,
635
704
  join,
636
705
  lastIndexOf,
637
706
  map,
@@ -659,6 +728,7 @@ declare namespace Functions {
659
728
  takeWhile,
660
729
  tap,
661
730
  tapChain,
731
+ union,
662
732
  withValue as with,
663
733
  zip
664
734
  }
@@ -672,6 +742,52 @@ export { Functions }
672
742
  */
673
743
  declare function getMemoizeDefaultOptions(): IMemoizeOptions;
674
744
 
745
+ /**
746
+ * Lazily yields one `[key, values]` pair for each key returned by `keySelector`, in the order of the first appearance of the key;
747
+ * the values of a group are in the order of the source.
748
+ * The whole source is read before the first group is yielded, so `groupBy` does not end on an infinite source.
749
+ * Every iteration reads the source again and builds new arrays.
750
+ * The keys are compared with `SameValueZero`, like `Map`: `NaN` is one key, `null` and `undefined` are keys too.
751
+ * If `keySelector` throws, the source is closed and the error propagates.
752
+ * @operation `Transformation`
753
+ * @param iterable - the source `Iterable`
754
+ * @param keySelector - called with each value and its index; returns the key of the group of the value
755
+ * @returns a lazy, re-runnable `Iterable` of `[key, values]` pairs
756
+ * @throws Error if `iterable` is missing or does not implement `[Symbol.iterator]`, or if `keySelector` is not a function
757
+ * @example
758
+ * ```ts
759
+ * Array.from(Functions.groupBy([1, 2, 3, 4, 5], v => v % 2)); // [[1, [1, 3, 5]], [0, [2, 4]]]
760
+ * ```
761
+ * @since 0.12.0
762
+ */
763
+ declare function groupBy<T, K>(iterable: Iterable<T>, keySelector: Mapper<T, K>): Iterable<[K, T[]]>;
764
+
765
+ /**
766
+ * Lazily yields `result(outer, inners)` for each value of `iterable`, with the values of `inner` that have the same key,
767
+ * in the order of `inner`; `inners` is empty when there are none.
768
+ * Before the first value it reads the whole `inner`, so `inner` must be finite; each run reads it again.
769
+ * The keys are compared with `SameValueZero`, like `Map`: `NaN` matches `NaN`, and `null` and `undefined` match themselves.
770
+ * Each call of `result` gets a new array.
771
+ * If a callback throws, or `inner` throws, the source is closed and the error propagates.
772
+ * @operation `Transformation`
773
+ * @param iterable - the source `Iterable`, the outer values
774
+ * @param inner - the `Iterable` whose values are joined to the outer values
775
+ * @param outerKey - called with each value of `iterable` and its index; returns its key
776
+ * @param innerKey - called with each value of `inner` and its index; returns its key
777
+ * @param result - called with each outer value and the array of its inner values; returns the value to yield
778
+ * @returns a lazy, re-runnable `Iterable` with one result for each value of `iterable`
779
+ * @throws Error if `iterable` or `inner` is missing or does not implement `[Symbol.iterator]`, or if `outerKey`, `innerKey` or `result` is not a function
780
+ * @example
781
+ * ```ts
782
+ * const teams = [{ id: 1, name: 'a' }, { id: 2, name: 'b' }];
783
+ * const players = [{ team: 1, name: 'x' }, { team: 1, name: 'y' }];
784
+ * Array.from(Functions.groupJoin(teams, players, t => t.id, p => p.team, (t, ps) => [t.name, ps.length]));
785
+ * // [['a', 2], ['b', 0]]
786
+ * ```
787
+ * @since 0.12.0
788
+ */
789
+ declare function groupJoin<T, I, K, R>(iterable: Iterable<T>, inner: Iterable<I>, outerKey: Mapper<T, K>, innerKey: Mapper<I, K>, result: (outer: T, inners: I[]) => R): Iterable<R>;
790
+
675
791
  /**
676
792
  * Fluent wrapper over an `Iterable`: every call builds a lazy, re-runnable operations chain.
677
793
  * Transformations and taps return a new `IIterableLinq`; actions run the chain and return a result.
@@ -915,6 +1031,24 @@ export declare interface IIterableLinqBase<T> {
915
1031
  * @since 0.5.0
916
1032
  */
917
1033
  every(predicate: Predicate<T>): boolean;
1034
+ /**
1035
+ * Yields the distinct values of the chain that are not in `other`, in the order of the chain.
1036
+ * Before the first value it reads the whole `other` into a `Set`, so `other` must be finite; each run reads it again.
1037
+ * Values, or the keys returned by `keySelector`, are compared with `SameValueZero`, like `Set`: for each key the first value is yielded.
1038
+ * If `keySelector` throws, or `other` throws, the sources are closed and the error propagates.
1039
+ * @operation `Transformation`
1040
+ * @param other - the `Iterable` whose values, or keys, are left out
1041
+ * @param keySelector - called with every value of the chain and of `other`, and its index in its own source; omitted or `undefined` compares the values
1042
+ * @returns a new lazy, re-runnable chain of the distinct values that are not in `other`
1043
+ * @throws Error if `other` is missing or does not implement `[Symbol.iterator]`, or if a provided `keySelector` is not a function
1044
+ * @example
1045
+ * ```ts
1046
+ * IterableLinq.from([1, 2, 2, 3]).except([3, 4]).collectToArray(); // [1, 2]
1047
+ * IterableLinq.from([{ id: 1 }, { id: 2 }]).except([{ id: 2 }], v => v.id).collectToArray(); // [{ id: 1 }]
1048
+ * ```
1049
+ * @since 0.12.0
1050
+ */
1051
+ except<K>(other: Iterable<T>, keySelector?: Mapper<T, K>): IIterableLinq<T>;
918
1052
  /**
919
1053
  * Keeps the values accepted by a type guard and narrows their type.
920
1054
  * If `predicate` throws, the source is closed and the error propagates.
@@ -1094,6 +1228,48 @@ export declare interface IIterableLinqBase<T> {
1094
1228
  * @since 0.0.11
1095
1229
  */
1096
1230
  forEachAsync(action: AsyncAction<T>): Promise<Unit>;
1231
+ /**
1232
+ * Yields one `[key, values]` pair for each key returned by `keySelector`, in the order of the first appearance of the key;
1233
+ * the values of a group are in the order of the chain.
1234
+ * The whole chain is read before the first group is yielded, so `groupBy` does not end on an infinite chain;
1235
+ * every run reads the chain again and builds new arrays.
1236
+ * The keys are compared with `SameValueZero`, like `Map`: `NaN` is one key, `null` and `undefined` are keys too.
1237
+ * If `keySelector` throws, the source is closed and the error propagates.
1238
+ * @operation `Transformation`
1239
+ * @param keySelector - called with each value and its index; returns the key of the group of the value
1240
+ * @returns a new chain of `[key, values]` pairs
1241
+ * @throws Error if `keySelector` is not a function
1242
+ * @example
1243
+ * ```ts
1244
+ * IterableLinq.from([1, 2, 3, 4, 5]).groupBy(v => v % 2).collectToArray(); // [[1, [1, 3, 5]], [0, [2, 4]]]
1245
+ * ```
1246
+ * @since 0.12.0
1247
+ */
1248
+ groupBy<K>(keySelector: Mapper<T, K>): IIterableLinq<[K, T[]]>;
1249
+ /**
1250
+ * Yields `result(outer, inners)` for each value of the chain, with the values of `inner` that have the same key,
1251
+ * in the order of `inner`; `inners` is empty when there are none. Like LINQ `GroupJoin`.
1252
+ * Before the first value it reads the whole `inner`, so `inner` must be finite; each run reads it again.
1253
+ * The keys are compared with `SameValueZero`, like `Map`: `NaN` matches `NaN`, and `null` and `undefined` match themselves.
1254
+ * Each call of `result` gets a new array.
1255
+ * If a callback throws, or `inner` throws, the source is closed and the error propagates.
1256
+ * @operation `Transformation`
1257
+ * @param inner - the `Iterable` whose values are joined to the values of the chain
1258
+ * @param outerKey - called with each value of the chain and its index; returns its key
1259
+ * @param innerKey - called with each value of `inner` and its index; returns its key
1260
+ * @param result - called with each value of the chain and the array of its inner values; returns the value to yield
1261
+ * @returns a new chain with one result for each value of the chain
1262
+ * @throws Error if `inner` is not iterable, or if `outerKey`, `innerKey` or `result` is not a function
1263
+ * @example
1264
+ * ```ts
1265
+ * const players = [{ team: 1, name: 'x' }, { team: 1, name: 'y' }];
1266
+ * IterableLinq.from([{ id: 1, name: 'a' }, { id: 2, name: 'b' }])
1267
+ * .groupJoin(players, t => t.id, p => p.team, (t, ps) => [t.name, ps.length])
1268
+ * .collectToArray(); // [['a', 2], ['b', 0]]
1269
+ * ```
1270
+ * @since 0.12.0
1271
+ */
1272
+ groupJoin<I, K, R>(inner: Iterable<I>, outerKey: Mapper<T, K>, innerKey: Mapper<I, K>, result: (outer: T, inners: I[]) => R): IIterableLinq<R>;
1097
1273
  /**
1098
1274
  * Tells whether the chain contains `value`, compared with `SameValueZero` like `Array.prototype.includes`;
1099
1275
  * stops and closes the source at the first match.
@@ -1120,6 +1296,48 @@ export declare interface IIterableLinqBase<T> {
1120
1296
  * @since 0.6.0
1121
1297
  */
1122
1298
  indexOf(value: T): number;
1299
+ /**
1300
+ * Yields `result(outer, inner)` for each pair of a value of the chain and a value of `inner` with the same key:
1301
+ * in the order of the chain, and for each value of the chain in the order of `inner`. A value without a match yields nothing.
1302
+ * Like LINQ `Join`; named `innerJoin` because `join` is the string join of `Array.prototype`.
1303
+ * Before the first value it reads the whole `inner`, so `inner` must be finite; each run reads it again.
1304
+ * The keys are compared with `SameValueZero`, like `Map`: `NaN` matches `NaN`, and `null` and `undefined` match themselves.
1305
+ * If a callback throws, or `inner` throws, the source is closed and the error propagates.
1306
+ * @operation `Transformation`
1307
+ * @param inner - the `Iterable` whose values are joined to the values of the chain
1308
+ * @param outerKey - called with each value of the chain and its index; returns its key
1309
+ * @param innerKey - called with each value of `inner` and its index; returns its key
1310
+ * @param result - called with each pair of values with the same key; returns the value to yield
1311
+ * @returns a new chain with one result for each pair of values with the same key
1312
+ * @throws Error if `inner` is not iterable, or if `outerKey`, `innerKey` or `result` is not a function
1313
+ * @example
1314
+ * ```ts
1315
+ * const players = [{ team: 1, name: 'x' }, { team: 1, name: 'y' }];
1316
+ * IterableLinq.from([{ id: 1, name: 'a' }, { id: 2, name: 'b' }])
1317
+ * .innerJoin(players, t => t.id, p => p.team, (t, p) => `${t.name}-${p.name}`)
1318
+ * .collectToArray(); // ['a-x', 'a-y']
1319
+ * ```
1320
+ * @since 0.12.0
1321
+ */
1322
+ innerJoin<I, K, R>(inner: Iterable<I>, outerKey: Mapper<T, K>, innerKey: Mapper<I, K>, result: (outer: T, inner: I) => R): IIterableLinq<R>;
1323
+ /**
1324
+ * Yields the distinct values of the chain that are also in `other`, in the order of the chain.
1325
+ * Before the first value it reads the whole `other` into a `Set`, so `other` must be finite; each run reads it again.
1326
+ * Values, or the keys returned by `keySelector`, are compared with `SameValueZero`, like `Set`: for each key the first value is yielded.
1327
+ * If `keySelector` throws, or `other` throws, the sources are closed and the error propagates.
1328
+ * @operation `Transformation`
1329
+ * @param other - the `Iterable` whose values, or keys, are kept
1330
+ * @param keySelector - called with every value of the chain and of `other`, and its index in its own source; omitted or `undefined` compares the values
1331
+ * @returns a new lazy, re-runnable chain of the distinct values that are in `other`
1332
+ * @throws Error if `other` is missing or does not implement `[Symbol.iterator]`, or if a provided `keySelector` is not a function
1333
+ * @example
1334
+ * ```ts
1335
+ * IterableLinq.from([1, 2, 2, 3]).intersect([2, 3, 4]).collectToArray(); // [2, 3]
1336
+ * IterableLinq.from([{ id: 1 }, { id: 2 }]).intersect([{ id: 2 }], v => v.id).collectToArray(); // [{ id: 2 }]
1337
+ * ```
1338
+ * @since 0.12.0
1339
+ */
1340
+ intersect<K>(other: Iterable<T>, keySelector?: Mapper<T, K>): IIterableLinq<T>;
1123
1341
  /**
1124
1342
  * Joins the values of the chain in a string, like `Array.prototype.join`; runs the whole chain.
1125
1343
  * `null` and `undefined` become empty strings, every other value is converted with its `toString`.
@@ -1309,12 +1527,13 @@ export declare interface IIterableLinqBase<T> {
1309
1527
  * If `equals` throws, both sources are closed and the error propagates; if a source throws, the other one is closed.
1310
1528
  * @operation `Action`
1311
1529
  * @param other - the `Iterable` to compare with, for example another chain
1312
- * @param equals - called with a value of the chain and the value of `other` at the same position; defaults to `===`
1530
+ * @param equals - called with a value of the chain and the value of `other` at the same position; defaults to `SameValueZero`, like `Set` and `Map`: `NaN` equals `NaN`, `+0` equals `-0`, objects are compared by reference
1313
1531
  * @returns `true` if the two sources have the same number of values and every pair is equal
1314
1532
  * @throws Error if `other` is missing or does not implement `[Symbol.iterator]`, or if a provided `equals` is not a function
1315
1533
  * @example
1316
1534
  * ```ts
1317
1535
  * IterableLinq.from([1, 2, 3]).sequenceEqual([1, 2, 3]); // true
1536
+ * IterableLinq.from([NaN]).sequenceEqual([NaN]); // true
1318
1537
  * IterableLinq.from(['a', 'bb']).sequenceEqual(['x', 'yy'], (a, b) => a.length === b.length); // true
1319
1538
  * ```
1320
1539
  * @since 0.7.0
@@ -1584,6 +1803,24 @@ export declare interface IIterableLinqBase<T> {
1584
1803
  * @since 0.0.10
1585
1804
  */
1586
1805
  tapChainCreation(chainCreationTapper: (chain: IIterableLinq<T>) => Unit): IIterableLinq<T>;
1806
+ /**
1807
+ * Yields the distinct values of the chain, then the values of `other` not yielded yet.
1808
+ * `other` is opened only when the chain ends, so after an infinite chain it is never read; stopping early closes only the source being read.
1809
+ * Values, or the keys returned by `keySelector`, are compared with `SameValueZero`, like `Set`: for each key the first value is yielded.
1810
+ * If `keySelector` throws, the source being read is closed and the error propagates.
1811
+ * @operation `Transformation`
1812
+ * @param other - the `Iterable` read after the chain
1813
+ * @param keySelector - called with every value and its index in its own source (from 0 again for `other`); omitted or `undefined` compares the values
1814
+ * @returns a new lazy, re-runnable chain of the distinct values of the chain and of `other`
1815
+ * @throws Error if `other` is missing or does not implement `[Symbol.iterator]`, or if a provided `keySelector` is not a function
1816
+ * @example
1817
+ * ```ts
1818
+ * IterableLinq.from([1, 2, 2]).union([2, 3]).collectToArray(); // [1, 2, 3]
1819
+ * IterableLinq.from([{ id: 1 }]).union([{ id: 1 }, { id: 2 }], v => v.id).collectToArray(); // [{ id: 1 }, { id: 2 }]
1820
+ * ```
1821
+ * @since 0.12.0
1822
+ */
1823
+ union<K>(other: Iterable<T>, keySelector?: Mapper<T, K>): IIterableLinq<T>;
1587
1824
  /**
1588
1825
  * Lazily yields the values of the chain, with `value` in place of the value at `index`, like `Array.prototype.with`; a negative index counts from the end.
1589
1826
  * A non-negative index yields the values as they are read. A negative index yields each value once `-index` more values have been read,
@@ -1661,6 +1898,78 @@ declare function includes<T>(iterable: Iterable<T>, value: T): boolean;
1661
1898
  */
1662
1899
  declare function indexOf<T>(iterable: Iterable<T>, value: T): number;
1663
1900
 
1901
+ /**
1902
+ * Lazily yields `result(outer, inner)` for each pair of a value of `iterable` and a value of `inner` with the same key:
1903
+ * in the order of `iterable`, and for each outer value in the order of `inner`. An outer value without a match yields nothing.
1904
+ * Named `innerJoin` because `join` is the string join of `Array.prototype`.
1905
+ * Before the first value it reads the whole `inner`, so `inner` must be finite; each run reads it again.
1906
+ * The keys are compared with `SameValueZero`, like `Map`: `NaN` matches `NaN`, and `null` and `undefined` match themselves.
1907
+ * If a callback throws, or `inner` throws, the source is closed and the error propagates.
1908
+ * @operation `Transformation`
1909
+ * @param iterable - the source `Iterable`, the outer values
1910
+ * @param inner - the `Iterable` whose values are joined to the outer values
1911
+ * @param outerKey - called with each value of `iterable` and its index; returns its key
1912
+ * @param innerKey - called with each value of `inner` and its index; returns its key
1913
+ * @param result - called with each pair of values with the same key; returns the value to yield
1914
+ * @returns a lazy, re-runnable `Iterable` with one result for each pair of values with the same key
1915
+ * @throws Error if `iterable` or `inner` is missing or does not implement `[Symbol.iterator]`, or if `outerKey`, `innerKey` or `result` is not a function
1916
+ * @example
1917
+ * ```ts
1918
+ * const teams = [{ id: 1, name: 'a' }, { id: 2, name: 'b' }];
1919
+ * const players = [{ team: 1, name: 'x' }, { team: 1, name: 'y' }];
1920
+ * Array.from(Functions.innerJoin(teams, players, t => t.id, p => p.team, (t, p) => `${t.name}-${p.name}`));
1921
+ * // ['a-x', 'a-y']
1922
+ * ```
1923
+ * @since 0.12.0
1924
+ */
1925
+ declare function innerJoin<T, I, K, R>(iterable: Iterable<T>, inner: Iterable<I>, outerKey: Mapper<T, K>, innerKey: Mapper<I, K>, result: (outer: T, inner: I) => R): Iterable<R>;
1926
+
1927
+ /**
1928
+ * Lazily yields the distinct values of `iterable` that are also in `other`, in the order of `iterable`.
1929
+ * Before the first value it reads the whole `other` into a `Set`, so `other` must be finite; each run reads it again.
1930
+ * Values, or the keys returned by `keySelector`, are compared with `SameValueZero`, like `Set`: for each key the first value of `iterable` is yielded.
1931
+ * If `keySelector` throws, or `other` throws, the sources are closed and the error propagates.
1932
+ * @operation `Transformation`
1933
+ * @param iterable - the source `Iterable`
1934
+ * @param other - the `Iterable` whose values, or keys, are kept
1935
+ * @param keySelector - called with every value of `iterable` and of `other`, and its index in its own source; omitted or `undefined` compares the values
1936
+ * @returns a lazy, re-runnable `Iterable` of the distinct values of `iterable` that are in `other`
1937
+ * @throws Error if `iterable` or `other` is missing or does not implement `[Symbol.iterator]`, or if a provided `keySelector` is not a function
1938
+ * @example
1939
+ * ```ts
1940
+ * Array.from(Functions.intersect([1, 2, 2, 3], [2, 3, 4])); // [2, 3]
1941
+ * Array.from(Functions.intersect([{ id: 1 }, { id: 2 }], [{ id: 2 }], v => v.id)); // [{ id: 2 }]
1942
+ * ```
1943
+ * @since 0.12.0
1944
+ */
1945
+ declare function intersect<T, K>(iterable: Iterable<T>, other: Iterable<T>, keySelector?: Mapper<T, K>): Iterable<T>;
1946
+
1947
+ /**
1948
+ * The options of `fromObject` when none are given: the type of the values follows `Object.entries`.
1949
+ * @since 0.11.0
1950
+ */
1951
+ export declare interface IObjectDefaultOptions extends IObjectOptions {
1952
+ yield?: 'entries';
1953
+ inherited?: false;
1954
+ nonEnumerable?: false;
1955
+ symbols?: false;
1956
+ }
1957
+
1958
+ /**
1959
+ * Options of `fromObject`. The defaults read what `Object.keys` reads: the own, enumerable, string keys.
1960
+ * @since 0.11.0
1961
+ */
1962
+ export declare interface IObjectOptions {
1963
+ /** `'entries'` (default) yields `[key, value]`, `'keys'` the keys, `'values'` the values, `'descriptors'` `[key, descriptor, owner]` without calling the getters. */
1964
+ yield?: ObjectYield;
1965
+ /** Also reads the properties of the prototype chain, up to `Object.prototype` excluded; defaults to `false`. */
1966
+ inherited?: boolean;
1967
+ /** Also reads the non-enumerable properties; defaults to `false`. */
1968
+ nonEnumerable?: boolean;
1969
+ /** Also reads the symbol keys; defaults to `false`. */
1970
+ symbols?: boolean;
1971
+ }
1972
+
1664
1973
  /**
1665
1974
  * Options of `range`.
1666
1975
  * @since 0.1.0
@@ -1811,6 +2120,39 @@ declare function memoize<T>(iterable: Iterable<T>, options?: IMemoizeOptions): I
1811
2120
  */
1812
2121
  declare function min<T>(iterable: Iterable<T>, comparer?: Comparer<T>): T | undefined;
1813
2122
 
2123
+ /**
2124
+ * The type of the values of `fromObject(object, options)`, chosen by `options.yield` (default `'entries'`).
2125
+ * @since 0.11.0
2126
+ */
2127
+ export declare type ObjectItem<O, Options extends IObjectOptions> = ObjectItemOf<O, Options, Options extends {
2128
+ yield: infer Y;
2129
+ } ? Y : Options extends {
2130
+ yield?: infer Y;
2131
+ } ? Y | undefined : undefined>;
2132
+
2133
+ /** Distributes over `Y`, so a `yield` typed as a union gives the union of the items; `undefined` gives the entries. */
2134
+ declare type ObjectItemOf<O, Options extends IObjectOptions, Y> = Y extends 'keys' ? ObjectKey<O, Options> : Y extends 'values' ? ObjectValue<O, Options> : Y extends 'descriptors' ? [ObjectKey<O, Options>, PropertyDescriptor, object] : [ObjectKey<O, Options>, ObjectValue<O, Options>];
2135
+
2136
+ /**
2137
+ * The type of the keys `fromObject` yields: the keys of `O` as strings, as they are at runtime,
2138
+ * or `string` (and `symbol`) when the options read keys that `O` does not declare.
2139
+ * @since 0.11.0
2140
+ */
2141
+ export declare type ObjectKey<O, Options extends IObjectOptions> = ReadsWide<Options> extends true ? string | (ReadsSymbols<Options> extends true ? symbol : never) : `${Extract<keyof O, string | number>}` | (ReadsSymbols<Options> extends true ? Extract<keyof O, symbol> : never);
2142
+
2143
+ /**
2144
+ * The type of the values `fromObject` yields: the values of the keys of `O` it reads, or `unknown`
2145
+ * when the options read keys that `O` does not declare.
2146
+ * @since 0.11.0
2147
+ */
2148
+ export declare type ObjectValue<O, Options extends IObjectOptions> = ReadsWide<Options> extends true ? unknown : O[Extract<keyof O, string | number> | (ReadsSymbols<Options> extends true ? Extract<keyof O, symbol> : never)];
2149
+
2150
+ /**
2151
+ * What `fromObject` yields for each property.
2152
+ * @since 0.11.0
2153
+ */
2154
+ export declare type ObjectYield = 'entries' | 'keys' | 'values' | 'descriptors';
2155
+
1814
2156
  /**
1815
2157
  * Replaces an existing method of every chain: a library method or one added with `extend`.
1816
2158
  * Typical use: a library release adds a method with the same name as one of your extensions,
@@ -1890,6 +2232,21 @@ declare function range(end: number, options?: IRangeOptions): Iterable<number>;
1890
2232
  */
1891
2233
  declare function range(start: number, end: number, options?: IRangeOptions): Iterable<number>;
1892
2234
 
2235
+ declare type ReadsSymbols<Options extends IObjectOptions> = Options extends {
2236
+ yield?: unknown;
2237
+ inherited?: unknown;
2238
+ nonEnumerable?: unknown;
2239
+ symbols?: false;
2240
+ } ? false : true;
2241
+
2242
+ /** `true` when the options may read keys that are not in `keyof O`: inherited or non-enumerable ones. */
2243
+ declare type ReadsWide<Options extends IObjectOptions> = Options extends {
2244
+ yield?: unknown;
2245
+ inherited?: false;
2246
+ nonEnumerable?: false;
2247
+ symbols?: unknown;
2248
+ } ? false : true;
2249
+
1893
2250
  /**
1894
2251
  * Accumulates the values of `iterable` into a single result, starting from the first value.
1895
2252
  * @operation `Action`
@@ -2016,13 +2373,14 @@ declare function reverse<T>(iterable: Iterable<T>): Iterable<T>;
2016
2373
  * @operation `Action`
2017
2374
  * @param iterable - the source `Iterable`
2018
2375
  * @param other - the `Iterable` to compare with
2019
- * @param equals - called with a value of `iterable` and the value of `other` at the same position; defaults to `===`
2376
+ * @param equals - called with a value of `iterable` and the value of `other` at the same position; defaults to `SameValueZero`, like `Set` and `Map`: `NaN` equals `NaN`, `+0` equals `-0`, objects are compared by reference
2020
2377
  * @returns `true` if the two sources have the same number of values and every pair is equal
2021
2378
  * @throws Error if `iterable` or `other` is missing or does not implement `[Symbol.iterator]`, or if a provided `equals` is not a function
2022
2379
  * @example
2023
2380
  * ```ts
2024
2381
  * Functions.sequenceEqual([1, 2, 3], [1, 2, 3]); // true
2025
2382
  * Functions.sequenceEqual([1, 2], [1, 2, 3]); // false
2383
+ * Functions.sequenceEqual([NaN], [NaN]); // true
2026
2384
  * Functions.sequenceEqual([{ id: 1 }], [{ id: 1 }], (a, b) => a.id === b.id); // true
2027
2385
  * ```
2028
2386
  * @since 0.7.0
@@ -2317,6 +2675,26 @@ declare function tapChain<T>(iterable: Iterable<T>, tapper: Tapper<Iterable<T>>)
2317
2675
  */
2318
2676
  export declare type Tapper<T> = (value: T, index: number) => Unit;
2319
2677
 
2678
+ /**
2679
+ * Lazily yields the distinct values of `iterable`, then the values of `other` not yielded yet.
2680
+ * `other` is opened only when `iterable` ends, so after an infinite source it is never read; stopping early closes only the source being read.
2681
+ * Values, or the keys returned by `keySelector`, are compared with `SameValueZero`, like `Set`: for each key the first value is yielded.
2682
+ * If `keySelector` throws, the source being read is closed and the error propagates.
2683
+ * @operation `Transformation`
2684
+ * @param iterable - the source `Iterable`
2685
+ * @param other - the `Iterable` read after the source
2686
+ * @param keySelector - called with every value and its index in its own source (from 0 again for `other`); omitted or `undefined` compares the values
2687
+ * @returns a lazy, re-runnable `Iterable` of the distinct values of `iterable` and `other`
2688
+ * @throws Error if `iterable` or `other` is missing or does not implement `[Symbol.iterator]`, or if a provided `keySelector` is not a function
2689
+ * @example
2690
+ * ```ts
2691
+ * Array.from(Functions.union([1, 2, 2], [2, 3])); // [1, 2, 3]
2692
+ * Array.from(Functions.union([{ id: 1 }], [{ id: 1 }, { id: 2 }], v => v.id)); // [{ id: 1 }, { id: 2 }]
2693
+ * ```
2694
+ * @since 0.12.0
2695
+ */
2696
+ declare function union<T, K>(iterable: Iterable<T>, other: Iterable<T>, keySelector?: Mapper<T, K>): Iterable<T>;
2697
+
2320
2698
  /**
2321
2699
  * The type with exactly one value, `unit()`: what an action or a tapper returns when it has nothing to return.
2322
2700
  * It is nominal: no other value (numbers, strings, objects, `\{\}`) is assignable to `Unit`.