@thi.ng/transducers
Advanced tools
Comparing version 0.9.0 to 0.10.0
import { Reduced } from "./reduced"; | ||
export declare type Fn<A, B> = (x: A) => B; | ||
export declare type Transducer<A, B> = (rfn: Reducer<any, B>) => Reducer<any, A>; | ||
@@ -8,2 +9,7 @@ export interface Reducer<A, B> extends Array<any> { | ||
} | ||
export interface StructField extends Array<any> { | ||
[0]: string; | ||
[1]: number; | ||
[2]?: Fn<any[], any>; | ||
} | ||
export declare const SEMAPHORE: symbol; |
@@ -34,8 +34,4 @@ "use strict"; | ||
function compR(rfn, fn) { | ||
return [ | ||
() => rfn[0](), | ||
(acc) => rfn[1](acc), | ||
fn, | ||
]; | ||
return [rfn[0], rfn[1], fn]; | ||
} | ||
exports.compR = compR; |
@@ -1,3 +0,3 @@ | ||
export declare type Fn<A, B> = (x: A) => B; | ||
export declare function juxt<T, A>(a: Fn<T, A>): Fn<T, A>; | ||
import { Fn } from "../api"; | ||
export declare function juxt<T, A>(a: Fn<T, A>): Fn<T, [A]>; | ||
export declare function juxt<T, A, B>(a: Fn<T, A>, b: Fn<T, B>): Fn<T, [A, B]>; | ||
@@ -4,0 +4,0 @@ export declare function juxt<T, A, B, C>(a: Fn<T, A>, b: Fn<T, B>, c: Fn<T, C>): Fn<T, [A, B, C]>; |
@@ -7,3 +7,3 @@ "use strict"; | ||
case 1: | ||
return a; | ||
return (x) => [a(x)]; | ||
case 2: | ||
@@ -10,0 +10,0 @@ return (x) => [a(x), b(x)]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const constantly_1 = require("../iter/constantly"); | ||
const repeat_1 = require("../iter/repeat"); | ||
const tuples_1 = require("../iter/tuples"); | ||
function weightedRandom(choices, weights) { | ||
const n = choices.length, opts = [...tuples_1.tuples(choices, weights || constantly_1.constantly(1))].sort((a, b) => b[1] - a[1]); | ||
const n = choices.length, opts = [...tuples_1.tuples(choices, weights || repeat_1.repeat(1))].sort((a, b) => b[1] - a[1]); | ||
let total = 0, i, r, sum; | ||
@@ -8,0 +8,0 @@ for (i = 0; i < n; i++) { |
@@ -16,2 +16,3 @@ export * from "./api"; | ||
export * from "./rfn/group-by-obj"; | ||
export * from "./rfn/join"; | ||
export * from "./rfn/last"; | ||
@@ -26,2 +27,3 @@ export * from "./rfn/max-compare"; | ||
export * from "./rfn/push"; | ||
export * from "./xform/base64"; | ||
export * from "./xform/benchmark"; | ||
@@ -47,2 +49,3 @@ export * from "./xform/bits"; | ||
export * from "./xform/map-indexed"; | ||
export * from "./xform/map-keys"; | ||
export * from "./xform/map-nth"; | ||
@@ -54,2 +57,3 @@ export * from "./xform/map"; | ||
export * from "./xform/partition-by"; | ||
export * from "./xform/partition-of"; | ||
export * from "./xform/partition-sort"; | ||
@@ -65,2 +69,3 @@ export * from "./xform/partition"; | ||
export * from "./xform/stream-sort"; | ||
export * from "./xform/struct"; | ||
export * from "./xform/swizzle"; | ||
@@ -74,3 +79,5 @@ export * from "./xform/take-nth"; | ||
export * from "./func/comp"; | ||
export * from "./func/constantly"; | ||
export * from "./func/delay"; | ||
export * from "./func/even"; | ||
export * from "./func/hex"; | ||
@@ -80,2 +87,3 @@ export * from "./func/identity"; | ||
export * from "./func/key-selector"; | ||
export * from "./func/odd"; | ||
export * from "./func/renamer"; | ||
@@ -85,3 +93,2 @@ export * from "./func/swizzler"; | ||
export * from "./iter/choices"; | ||
export * from "./iter/constantly"; | ||
export * from "./iter/cycle"; | ||
@@ -88,0 +95,0 @@ export * from "./iter/iterate"; |
@@ -21,2 +21,3 @@ "use strict"; | ||
__export(require("./rfn/group-by-obj")); | ||
__export(require("./rfn/join")); | ||
__export(require("./rfn/last")); | ||
@@ -31,2 +32,3 @@ __export(require("./rfn/max-compare")); | ||
__export(require("./rfn/push")); | ||
__export(require("./xform/base64")); | ||
__export(require("./xform/benchmark")); | ||
@@ -52,2 +54,3 @@ __export(require("./xform/bits")); | ||
__export(require("./xform/map-indexed")); | ||
__export(require("./xform/map-keys")); | ||
__export(require("./xform/map-nth")); | ||
@@ -59,2 +62,3 @@ __export(require("./xform/map")); | ||
__export(require("./xform/partition-by")); | ||
__export(require("./xform/partition-of")); | ||
__export(require("./xform/partition-sort")); | ||
@@ -70,2 +74,3 @@ __export(require("./xform/partition")); | ||
__export(require("./xform/stream-sort")); | ||
__export(require("./xform/struct")); | ||
__export(require("./xform/swizzle")); | ||
@@ -79,3 +84,5 @@ __export(require("./xform/take-nth")); | ||
__export(require("./func/comp")); | ||
__export(require("./func/constantly")); | ||
__export(require("./func/delay")); | ||
__export(require("./func/even")); | ||
__export(require("./func/hex")); | ||
@@ -85,2 +92,3 @@ __export(require("./func/identity")); | ||
__export(require("./func/key-selector")); | ||
__export(require("./func/odd")); | ||
__export(require("./func/renamer")); | ||
@@ -90,3 +98,2 @@ __export(require("./func/swizzler")); | ||
__export(require("./iter/choices")); | ||
__export(require("./iter/constantly")); | ||
__export(require("./iter/cycle")); | ||
@@ -93,0 +100,0 @@ __export(require("./iter/iterate")); |
{ | ||
"name": "@thi.ng/transducers", | ||
"version": "0.9.0", | ||
"version": "0.10.0", | ||
"description": "Lightweight transducer implementations for ES6 / TypeScript", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -5,3 +5,3 @@ # @thi.ng/transducers | ||
Lightweight transducer implementations for ES6 / TypeScript (21KB minified, full lib). | ||
Lightweight transducer implementations for ES6 / TypeScript (~24KB minified, full lib). | ||
@@ -22,3 +22,3 @@ ## TOC | ||
Currently, the library provides altogether 70+ transducers, reducers and | ||
Currently, the library provides altogether 75+ transducers, reducers and | ||
sequence generators for composing data transformation pipelines. | ||
@@ -174,2 +174,26 @@ | ||
### Stream parsing / structuring | ||
The `struct` transducer is simply a composition of: `partitionOf -> partition -> rename -> mapKeys`. | ||
[See code here](https://github.com/thi-ng/transducers/blob/master/src/xform/struct.ts). | ||
```typescript | ||
// Higher-order transducer to convert linear input into structured objects | ||
// using given field specs and ordering. A single field spec is an array of | ||
// 2 or 3 items: `[name, size, transform?]`. If `transform` is given, it will | ||
// be used to produce the final value for this field. In the example below, | ||
// it is used to unwrap the ID field values, e.g. from `[0] => 0` | ||
[...tx.iterator( | ||
tx.struct([["id", 1, (id) => id[0]], ["pos", 2], ["vel", 2], ["color", 4]]), | ||
[0, 100, 200, -1, 0, 1, 0.5, 0, 1, 1, 0, 0, 5, 4, 0, 0, 1, 1]) ] | ||
// [ { color: [ 1, 0.5, 0, 1 ], | ||
// vel: [ -1, 0 ], | ||
// pos: [ 100, 200 ], | ||
// id: 0 }, | ||
// { color: [ 0, 0, 1, 1 ], | ||
// vel: [ 5, 4 ], | ||
// pos: [ 0, 0 ], | ||
// id: 1 } ] | ||
``` | ||
### CSV parsing | ||
@@ -251,3 +275,3 @@ | ||
```typescript | ||
[...tx.iterator(tx.comp(tx.bits(8), tx.partition(8)), [ 0xf0, 0xaa ])] | ||
[...tx.iterator(tx.bits(8), [ 0xf0, 0xaa ])] | ||
// [ 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0 ] | ||
@@ -273,2 +297,28 @@ | ||
### Base64 en/decoding | ||
```typescript | ||
// add offset (0x80) to allow negative values to be encoded | ||
// (URL safe result can be produced via opt arg to `base64Encode`) | ||
enc = tx.transduce( | ||
tx.comp( | ||
tx.map(x => x + 0x80), | ||
tx.base64Encode() | ||
), | ||
tx.join(), | ||
tx.range(-8, 8) | ||
); | ||
// "eHl6e3x9fn+AgYKDhIWGhw==" | ||
// remove offset again during decoding, but (for example) only decode while val < 0 | ||
[...tx.iterator( | ||
tx.comp( | ||
tx.base64Decode(), | ||
tx.map(x => x - 0x80), | ||
tx.takeWhile(x=> x < 0) | ||
), | ||
enc)] | ||
// [ -8, -7, -6, -5, -4, -3, -2, -1 ] | ||
``` | ||
### Weighted random choices | ||
@@ -429,2 +479,6 @@ | ||
#### `base64Decode(): Transducer<string, number>` | ||
#### `base64Encode(urlSafe?: boolean, bufSize?: number): Transducer<number, string>` | ||
#### `benchmark(): Transducer<any, number>` | ||
@@ -474,2 +528,4 @@ | ||
#### `mapKeys(keys: IObjectOf<(x: any) => any>, copy?: boolean): Transducer<any, any>` | ||
#### `mapNth<A, B>(n: number, offset: number, fn: (x: A) => B): Transducer<A, B>` | ||
@@ -485,2 +541,4 @@ | ||
#### `partitionOf<T>(sizes: number[]): Transducer<T, T[]>` | ||
#### `partitionSort<A, B>(n: number, key?: ((x: A) => B), cmp?: Comparator<B>): Transducer<A, A>` | ||
@@ -504,2 +562,4 @@ | ||
#### `struct<T>(fields: StructField[]): Transducer<any, T>` | ||
#### `swizzle<T>(order: PropertyKey[]): Transducer<T, any>` | ||
@@ -559,4 +619,2 @@ | ||
#### `constantly<T>(x: T): IterableIterator<T>` | ||
#### `cycle<T>(input: Iterable<T>): IterableIterator<T>` | ||
@@ -563,0 +621,0 @@ |
@@ -29,6 +29,6 @@ "use strict"; | ||
function padLast(n, fill) { | ||
return ([i, c, r]) => { | ||
return ([init, complete, reduce]) => { | ||
let m = 0; | ||
return [ | ||
() => i(), | ||
init, | ||
(acc) => { | ||
@@ -39,8 +39,8 @@ let rem = (m % n); | ||
while (rem-- > 0 && !reduced_1.isReduced(acc)) { | ||
acc = r(acc, fill); | ||
acc = reduce(acc, fill); | ||
} | ||
} | ||
return c(acc); | ||
return complete(acc); | ||
}, | ||
(acc, x) => (m++, r(acc, x)) | ||
(acc, x) => (m++, reduce(acc, x)) | ||
]; | ||
@@ -47,0 +47,0 @@ }; |
import { Transducer } from "../api"; | ||
export declare function partitionBy<T>(fn: (x: T) => any): Transducer<T, T[]>; | ||
export declare function partitionBy<T>(fn: (x?: T) => any, stateful?: boolean): Transducer<T, T[]>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const api_1 = require("../api"); | ||
const reduced_1 = require("../reduced"); | ||
function partitionBy(fn) { | ||
return ([i, c, r]) => { | ||
let prev = {}, chunk; | ||
function partitionBy(fn, stateful = false) { | ||
return ([init, complete, reduce]) => { | ||
const f = stateful ? fn() : fn; | ||
let prev = api_1.SEMAPHORE, chunk; | ||
return [ | ||
() => i(), | ||
init, | ||
(acc) => { | ||
if (chunk && chunk.length) { | ||
acc = r(acc, chunk); | ||
acc = reduce(acc, chunk); | ||
chunk = null; | ||
} | ||
return c(acc); | ||
return complete(acc); | ||
}, | ||
(acc, x) => { | ||
const curr = fn(x); | ||
if (curr === prev) { | ||
const curr = f(x); | ||
if (prev === api_1.SEMAPHORE) { | ||
prev = curr; | ||
chunk = [x]; | ||
} | ||
else if (curr === prev) { | ||
chunk.push(x); | ||
} | ||
else { | ||
chunk && (acc = r(acc, chunk)); | ||
chunk && (acc = reduce(acc, chunk)); | ||
chunk = reduced_1.isReduced(acc) ? null : [x]; | ||
@@ -24,0 +30,0 @@ prev = curr; |
@@ -13,12 +13,12 @@ "use strict"; | ||
} | ||
return ([i, c, r]) => { | ||
return ([init, complete, reduce]) => { | ||
let buf = [], skip = 0; | ||
return [ | ||
() => i(), | ||
init, | ||
(acc) => { | ||
if (buf.length && (all || buf.length === size)) { | ||
acc = r(acc, buf); | ||
acc = reduce(acc, buf); | ||
buf = []; | ||
} | ||
return c(acc); | ||
return complete(acc); | ||
}, | ||
@@ -31,3 +31,3 @@ (acc, x) => { | ||
if (buf.length === size) { | ||
acc = r(acc, buf); | ||
acc = reduce(acc, buf); | ||
buf = step < size ? buf.slice(step) : []; | ||
@@ -34,0 +34,0 @@ skip = step - size; |
@@ -6,12 +6,12 @@ "use strict"; | ||
function streamShuffle(n, maxSwaps = n) { | ||
return ([i, c, r]) => { | ||
return ([init, complete, reduce]) => { | ||
const buf = []; | ||
return [ | ||
() => i(), | ||
init, | ||
(acc) => { | ||
while (buf.length && !reduced_1.isReduced(acc)) { | ||
shuffle_1.shuffleN(buf, maxSwaps); | ||
acc = r(acc, buf.shift()); | ||
acc = reduce(acc, buf.shift()); | ||
} | ||
acc = c(acc); | ||
acc = complete(acc); | ||
return acc; | ||
@@ -23,3 +23,3 @@ }, | ||
if (buf.length === n) { | ||
acc = r(acc, buf.shift()); | ||
acc = reduce(acc, buf.shift()); | ||
} | ||
@@ -26,0 +26,0 @@ return acc; |
@@ -8,11 +8,11 @@ "use strict"; | ||
function streamSort(n, key = identity_1.identity, cmp = compare_1.compare) { | ||
return ([i, c, r]) => { | ||
return ([init, complete, reduce]) => { | ||
const buf = []; | ||
return [ | ||
() => i(), | ||
init, | ||
(acc) => { | ||
while (buf.length && !reduced_1.isReduced(acc)) { | ||
acc = r(acc, buf.shift()); | ||
acc = reduce(acc, buf.shift()); | ||
} | ||
return c(acc); | ||
return complete(acc); | ||
}, | ||
@@ -23,3 +23,3 @@ (acc, x) => { | ||
if (buf.length === n) { | ||
acc = r(acc, buf.shift()); | ||
acc = reduce(acc, buf.shift()); | ||
} | ||
@@ -26,0 +26,0 @@ return acc; |
@@ -5,11 +5,11 @@ "use strict"; | ||
function takeLast(n) { | ||
return ([i, c, r]) => { | ||
return ([init, complete, reduce]) => { | ||
const buf = []; | ||
return [ | ||
() => i(), | ||
init, | ||
(acc) => { | ||
while (buf.length && !reduced_1.isReduced(acc)) { | ||
acc = r(acc, buf.shift()); | ||
acc = reduce(acc, buf.shift()); | ||
} | ||
return c(acc); | ||
return complete(acc); | ||
}, | ||
@@ -16,0 +16,0 @@ (acc, x) => { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
110626
193
2307
632