From 17a0fa0a5512761759708f8c883ff9d7de484476 Mon Sep 17 00:00:00 2001 From: Ewan Breakey Date: Wed, 19 Jul 2023 15:14:37 +1000 Subject: [PATCH 1/3] Implement splitArray utility --- .changeset/brave-rings-retire.md | 5 ++++ lib/arrays/index.ts | 1 + lib/arrays/splitArray.ts | 41 ++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 .changeset/brave-rings-retire.md create mode 100644 lib/arrays/splitArray.ts diff --git a/.changeset/brave-rings-retire.md b/.changeset/brave-rings-retire.md new file mode 100644 index 0000000..61c17ca --- /dev/null +++ b/.changeset/brave-rings-retire.md @@ -0,0 +1,5 @@ +--- +"@giraugh/tools": minor +--- + +Add splitArray util diff --git a/lib/arrays/index.ts b/lib/arrays/index.ts index a3b5521..eb325d4 100644 --- a/lib/arrays/index.ts +++ b/lib/arrays/index.ts @@ -6,4 +6,5 @@ export * from './zipArrays' export * from './zipArraysLongest' export * from './partitionArray' export * from './rotateArray' +export * from './splitArray' export * from './splitArrayBy' diff --git a/lib/arrays/splitArray.ts b/lib/arrays/splitArray.ts new file mode 100644 index 0000000..e86d511 --- /dev/null +++ b/lib/arrays/splitArray.ts @@ -0,0 +1,41 @@ +/** + * Split an array when a predicate function determines an element is a predicate + * (similiar to String.prototype.split but for arrays) + * @param arr the array to split + * @param splitFn a function over elements in the array that determines whether an element is a delimeter. + * @returns the array of groups split as per the `splitFn` + * + * @example + * const groups = splitArrayBy([1, 3, 5, 6, 7, 9, 11], (x) => x % 2 === 0) // [[1, 3, 5], [7, 9, 11]] + */ +export const splitArray = (arr: T[], splitFn: (t: T) => boolean): T[][] => { + // Handle special case of empty array + if (arr.length === 0) return [] + + let groups: T[][] = [[]] + while (true) { + // Shift one element and peak the next element + if (arr.length === 0) break + const next = arr.shift()! + + // Split? + if (splitFn(next)) { + groups.push([]) + } else { + // Add element to current group + groups[groups.length - 1]!.push(next) + } + } + + return groups +} + +if (import.meta.vitest) { + const { expect, it } = import.meta.vitest + + it('works for example 1', () => { + const runs = splitArray([1, 3, 5, 6, 7, 9, 11], (x) => x % 2 === 0) + expect(runs).toEqual([[1, 3, 5], [7, 9, 11]]) + }) + +} From 9732e3940bc5f416f58dc1050e69bc22fdaa984f Mon Sep 17 00:00:00 2001 From: Ewan Breakey Date: Wed, 19 Jul 2023 16:04:27 +1000 Subject: [PATCH 2/3] FIx typo in example for splitArray --- lib/arrays/splitArray.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/arrays/splitArray.ts b/lib/arrays/splitArray.ts index e86d511..12bfac7 100644 --- a/lib/arrays/splitArray.ts +++ b/lib/arrays/splitArray.ts @@ -6,7 +6,7 @@ * @returns the array of groups split as per the `splitFn` * * @example - * const groups = splitArrayBy([1, 3, 5, 6, 7, 9, 11], (x) => x % 2 === 0) // [[1, 3, 5], [7, 9, 11]] + * const groups = splitArray([1, 3, 5, 6, 7, 9, 11], (x) => x % 2 === 0) // [[1, 3, 5], [7, 9, 11]] */ export const splitArray = (arr: T[], splitFn: (t: T) => boolean): T[][] => { // Handle special case of empty array From ae350dbe48f63f8cfa5dc331adab58c08c550cc0 Mon Sep 17 00:00:00 2001 From: Ewan Breakey Date: Wed, 19 Jul 2023 22:33:02 +1000 Subject: [PATCH 3/3] Update lib/arrays/splitArray.ts Co-authored-by: Benji Grant --- lib/arrays/splitArray.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/arrays/splitArray.ts b/lib/arrays/splitArray.ts index 12bfac7..e6bd5df 100644 --- a/lib/arrays/splitArray.ts +++ b/lib/arrays/splitArray.ts @@ -37,5 +37,15 @@ if (import.meta.vitest) { const runs = splitArray([1, 3, 5, 6, 7, 9, 11], (x) => x % 2 === 0) expect(runs).toEqual([[1, 3, 5], [7, 9, 11]]) }) + + it('handles an empty array', () => { + const runs = splitArray([], (x) => x === 0) + expect(runs).toEqual([]) + }) + + it('works if predicate is always true', () => { + const runs = splitArray(['a', 'b', 'c'], () => true) + expect(runs).toEqual([[], [], [], []]) + }) }