Skip to content

Commit

Permalink
Merge pull request #25 from giraugh/feat/split-array-fn
Browse files Browse the repository at this point in the history
`splitArray` utility
  • Loading branch information
giraugh authored Jul 19, 2023
2 parents 6e4f75b + ae350db commit 7d1659e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-rings-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@giraugh/tools": minor
---

Add splitArray util
1 change: 1 addition & 0 deletions lib/arrays/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export * from './zipArrays'
export * from './zipArraysLongest'
export * from './partitionArray'
export * from './rotateArray'
export * from './splitArray'
export * from './splitArrayBy'
51 changes: 51 additions & 0 deletions lib/arrays/splitArray.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* 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 = splitArray([1, 3, 5, 6, 7, 9, 11], (x) => x % 2 === 0) // [[1, 3, 5], [7, 9, 11]]
*/
export const splitArray = <T>(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]])
})

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([[], [], [], []])
})

}

0 comments on commit 7d1659e

Please sign in to comment.