Skip to content

Commit

Permalink
feat(transducers): add keyPermutations, tests, update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jun 12, 2020
1 parent 62f33b5 commit 5110d50
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/transducers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ yarn add @thi.ng/transducers
<script src="https://unpkg.com/@thi.ng/transducers/lib/index.umd.js" crossorigin></script>
```

Package sizes (gzipped, pre-treeshake): ESM: 8.00 KB / CJS: 8.54 KB / UMD: 7.72 KB
Package sizes (gzipped, pre-treeshake): ESM: 8.05 KB / CJS: 8.58 KB / UMD: 7.77 KB

## Dependencies

Expand Down Expand Up @@ -893,6 +893,7 @@ tx.transduce(tx.map((x) => x*10), tx.push(), tx.range(4))
- [dup](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/dup.ts)
- [extendSides](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/extend-sides.ts)
- [iterate](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/iterate.ts)
- [keyPermutations](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/key-permutations.ts)
- [keys](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/keys.ts)
- [line](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/line.ts)
- [normRange](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/norm-range.ts)
Expand Down
1 change: 1 addition & 0 deletions packages/transducers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export * from "./iter/cycle";
export * from "./iter/dup";
export * from "./iter/extend-sides";
export * from "./iter/iterate";
export * from "./iter/key-permutations";
export * from "./iter/keys";
export * from "./iter/line";
export * from "./iter/norm-range";
Expand Down
46 changes: 46 additions & 0 deletions packages/transducers/src/iter/key-permutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { IObjectOf, Pair } from "@thi.ng/api";
import { assocObj } from "../rfn/assoc-obj";
import { map } from "../xform/map";
import { mapcat } from "../xform/mapcat";
import { partition } from "../xform/partition";
import { pairs } from "./pairs";
import { permutations } from "./permutations";

/**
* Similar to {@link permutations}, however takes an object with each
* key specifying an array of its possible values. Yields an iterable of
* objects of all value permutations.
*
* @remarks
* The resulting object type will be derived from the value types in the
* given `spec` object.
*
* The order of resulting permutations is not guaranteed and depending
* on the VM's iteration behavior of `Object.keys()`.
*
* @example
* ```ts
* [...keyPermutations({ a: [1, 2], b: [true, false], c: ["X", "Y"] })]
* // [
* // { a: 1, b: true, c: 'X' },
* // { a: 1, b: true, c: 'Y' },
* // { a: 1, b: false, c: 'X' },
* // { a: 1, b: false, c: 'Y' },
* // { a: 2, b: true, c: 'X' },
* // { a: 2, b: true, c: 'Y' },
* // { a: 2, b: false, c: 'X' },
* // { a: 2, b: false, c: 'Y' }
* // ]
* ```
*
* @param spec - permutation spec object
*/
export const keyPermutations = <T extends IObjectOf<any[]>>(
spec: T
): IterableIterator<{ [k in keyof T]: T[k][0] }> =>
<any>(
map(
(x) => assocObj(<Iterable<Pair<string, any>>>partition(2, x)),
permutations(...mapcat(([k, v]) => [[k], v], pairs(spec)))
)
);
27 changes: 27 additions & 0 deletions packages/transducers/test/keyperms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { keyPermutations } from "../src";

import * as assert from "assert";

describe("keyPermutations", () => {
it("basic", () => {
assert.deepEqual(
new Set([
...keyPermutations({
a: [1, 2],
b: [true, false],
c: ["X", "Y"],
}),
]),
new Set([
{ a: 1, b: true, c: "X" },
{ a: 1, b: true, c: "Y" },
{ a: 1, b: false, c: "X" },
{ a: 1, b: false, c: "Y" },
{ a: 2, b: true, c: "X" },
{ a: 2, b: true, c: "Y" },
{ a: 2, b: false, c: "X" },
{ a: 2, b: false, c: "Y" },
])
);
});
});
1 change: 1 addition & 0 deletions packages/transducers/tpl.readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ tx.transduce(tx.map((x) => x*10), tx.push(), tx.range(4))
- [dup](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/dup.ts)
- [extendSides](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/extend-sides.ts)
- [iterate](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/iterate.ts)
- [keyPermutations](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/key-permutations.ts)
- [keys](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/keys.ts)
- [line](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/line.ts)
- [normRange](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers/src/iter/norm-range.ts)
Expand Down

0 comments on commit 5110d50

Please sign in to comment.