export function reduce<T, R>(this: Observable<T>, accumulator: (acc: R, value: T, index?: number) => R, seed?: R): Observable<R> { // providing a seed of `undefined` *should* be valid and trigger // hasSeed! so don't use `seed !== undefined` checks! // For this reason, we have to check it here at the original call site // otherwise inside Operator/Subscriber we won't know if `undefined` // means they didn't provide anything or if they literally provided `undefined` if (arguments.length >= 2) { return higherOrderReduce(accumulator, seed)(this); } return higherOrderReduce(accumulator)(this); }
function filterAny(values, getter) { return of(...values).pipe( map(x => getter(x)), reduce((a, b) => a.union(b), new TypedFastBitSet()), map(mask => results => results.intersection(mask)) ); }
type('should accept R typed reducers', () => { let a: Observable<{ a: number; b: string }>; a.pipe(reduce<{ a?: number; b?: string }>((acc, value) => { value.a = acc.a; value.b = acc.b; return acc; }, {})); });
async function getTrainingSet() { const peopleArray = await of(...range(5, 10), 2) .pipe(map(x => `https://swapi.co/api/people/?format=json&page=${x}`)) .pipe(flatMap(x => Axios.get(x).catch(console.error))) .pipe(map((x: AxiosResponse) => x.data)) .pipe(reduce((acc: any[], x: any) => [x, ...acc], [])) .toPromise(); console.log(JSON.stringify(peopleArray, null, 2)); }
type('should accept T typed reducers when T is an array', () => { let a: Observable<number[]>; const reduced = a.pipe(reduce((acc, value) => { return acc.concat(value); }, [])); reduced.subscribe(rs => { rs[0].toExponential(); }); });
type('should accept R typed reduces when R is an array of T', () => { let a: Observable<number>; const reduced = a.pipe(reduce<number>((acc, value) => { acc.push(value); return acc; }, [])); reduced.subscribe(rs => { rs[0].toExponential(); }); });
it('should reduce with index with seed', (done: MochaDone) => { const idx = [0, 1, 2, 3, 4, 5]; range(0, 6).pipe(reduce((acc, value, index) => { expect(idx.shift()).to.equal(index); return value; }, -1)).subscribe(null, null, () => { expect(idx).to.be.empty; done(); }); });
proc.on('close', (code: number) => { noClose = true; let pipesClosed = merge(stdoutCompleted!, stderrCompleted!) .pipe(reduce((acc) => acc, true)); if (code === 0) { pipesClosed.subscribe(() => subj.complete()); } else { pipesClosed.subscribe(() => subj.error(new Error(`Failed with exit code: ${code}`))); } });
it('should raise error if reduce function throws without seed', () => { const e1 = hot('--a--b--|'); const e1subs = '^ ! '; const expected = '-----# '; const reduceFunction = function (o: string, x: string) { throw 'error'; }; expectObservable(e1.pipe(reduce(reduceFunction))).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); });
it('should raise error if source raises error without seed', () => { const e1 = hot('----#'); const e1subs = '^ !'; const expected = '----#'; const reduceFunction = function (o: string, x: string) { return o + x; }; expectObservable(e1.pipe(reduce(reduceFunction))).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); });