From 077d05f7c4be31f884e798448d2b805566b7d2d1 Mon Sep 17 00:00:00 2001 From: ssube Date: Sat, 1 Aug 2020 10:01:00 -0500 Subject: [PATCH] feat(list): add filter many helper --- src/List.ts | 19 +++++++++++++++++++ test/utils/TestList.ts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 test/utils/TestList.ts diff --git a/src/List.ts b/src/List.ts index d668bfda..d59b92c1 100644 --- a/src/List.ts +++ b/src/List.ts @@ -63,3 +63,22 @@ export function isList(list: TVal | ReadonlyArray): list is Readonly export function isList(list: TVal | ReadonlyArray): list is ReadonlyArray { return Array.isArray(list); } + +export function isEmpty(val: Optional | ReadonlyArray>): boolean { + return !Array.isArray(val) || val.length === 0; +} + +export function filterMany(cb: (a: T1) => boolean, l1: Array): Array; +export function filterMany(cb: (a: T1, b: T2) => boolean, l1: Array, l2: Array): [Array, Array]; +export function filterMany(cb: (a: T1, b: T2) => boolean, l1: Array, l2: Array, l3: Array): [Array, Array, Array]; +export function filterMany(cb: (a: T1, b: T2) => boolean, l1: Array, l2: Array, l3: Array, l4: Array): [Array, Array, Array, Array]; +export function filterMany(cb: (...d: Array) => boolean, ...l: Array>): Array> { + const results = []; + for (let i = 0; i < l[0].length; ++i) { + const slice = l.map((li) => li[i]); + if (cb(...slice)) { + results.push(slice); + } + } + return results; +} diff --git a/test/utils/TestList.ts b/test/utils/TestList.ts new file mode 100644 index 00000000..0ffd10cf --- /dev/null +++ b/test/utils/TestList.ts @@ -0,0 +1,35 @@ +import { expect } from 'chai'; +import { match, stub } from 'sinon'; + +import { filterMany } from '../../src/List'; + +describe('list utils', async () => { + describe('filter many helper', async () => { + it('should call the predicate with an item from each list', async () => { + const cb = stub().returns(true); + const results = filterMany(cb, [1], ['a']); + + expect(results.length).to.equal(1); + expect(cb).to.have.callCount(1); + expect(cb).to.have.been.calledWithMatch(match.number, match.string); + }); + + it('should call the predicate for each slice', async () => { + const data = [1, 2, 3, 4, 5]; + const cb = stub().returns(true); + const results = filterMany(cb, data); + + expect(results.length).to.equal(data.length); + expect(cb).to.have.callCount(data.length); + }); + + it('should keep slices that passed the predicate', async () => { + const data = [1, 2, 3, 4, 5]; + const cb = stub().returns(false); + const results = filterMany(cb, data); + + expect(results.length).to.equal(0); + expect(cb).to.have.callCount(data.length); + }); + }); +});