-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dfts-helper): add a_chunk and a_hashFrom
- Loading branch information
Showing
5 changed files
with
275 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
libs/dfts-helper/src/lib/helper/array/chunk/chunk.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import { a_chunk } from './chunk'; | ||
|
||
describe('a_chunk', () => { | ||
test('splits an evenly divisible array correctly', () => { | ||
const input = [1, 2, 3, 4, 5, 6]; | ||
const result = a_chunk(input, 2); | ||
expect(result).toEqual([ | ||
[1, 2], | ||
[3, 4], | ||
[5, 6], | ||
]); | ||
}); | ||
|
||
test('handles chunk size of 1', () => { | ||
const input = [1, 2, 3]; | ||
const result = a_chunk(input, 1); | ||
expect(result).toEqual([[1], [2], [3]]); | ||
}); | ||
|
||
test('returns empty array when given an empty array', () => { | ||
const input: number[] = []; | ||
const result = a_chunk(input, 2); | ||
expect(result).toEqual([]); | ||
}); | ||
|
||
test('returns one chunk if chunk size equals the entire array length', () => { | ||
const input = [1, 2, 3, 4]; | ||
const result = a_chunk(input, 4); | ||
expect(result).toEqual([[1, 2, 3, 4]]); | ||
}); | ||
|
||
test('last chunk may be smaller if array length is not divisible by chunk size', () => { | ||
const input = [1, 2, 3, 4, 5]; | ||
const result = a_chunk(input, 2); | ||
expect(result).toEqual([[1, 2], [3, 4], [5]]); | ||
}); | ||
|
||
test('handles chunk size larger than the array length', () => { | ||
const input = [1, 2, 3]; | ||
const result = a_chunk(input, 10); | ||
expect(result).toEqual([[1, 2, 3]]); | ||
}); | ||
|
||
test('works with different data types (strings)', () => { | ||
const input = ['a', 'b', 'c', 'd']; | ||
const result = a_chunk(input, 2); | ||
expect(result).toEqual([ | ||
['a', 'b'], | ||
['c', 'd'], | ||
]); | ||
}); | ||
|
||
test('works with mixed data types', () => { | ||
const input = [1, 'two', { three: 3 }, [4], null]; | ||
const result = a_chunk(input, 2); | ||
expect(result).toEqual([[1, 'two'], [{ three: 3 }, [4]], [null]]); | ||
}); | ||
|
||
test('handles a chunk size of 3', () => { | ||
const input = [1, 2, 3, 4, 5, 6, 7]; | ||
const result = a_chunk(input, 3); | ||
expect(result).toEqual([[1, 2, 3], [4, 5, 6], [7]]); | ||
}); | ||
|
||
test('does not modify the original array', () => { | ||
const input = [1, 2, 3, 4, 5]; | ||
const copy = [...input]; | ||
a_chunk(input, 2); | ||
expect(input).toEqual(copy); | ||
}); | ||
|
||
test('handles a large array efficiently', () => { | ||
const input = Array.from({ length: 1000 }, (_, i) => i + 1); | ||
const result = a_chunk(input, 100); | ||
expect(result.length).toBe(10); | ||
expect(result[0].length).toBe(100); | ||
}); | ||
|
||
test('handles chunk size equal to 2 with odd length input', () => { | ||
const input = [1, 2, 3]; | ||
const result = a_chunk(input, 2); | ||
expect(result).toEqual([[1, 2], [3]]); | ||
}); | ||
|
||
test('handles chunk size equal to the first half of array length', () => { | ||
const input = [1, 2, 3, 4, 5, 6]; | ||
const result = a_chunk(input, 3); | ||
expect(result).toEqual([ | ||
[1, 2, 3], | ||
[4, 5, 6], | ||
]); | ||
}); | ||
|
||
test('works with a single-element array', () => { | ||
const input = [42]; | ||
const result = a_chunk(input, 5); | ||
expect(result).toEqual([[42]]); | ||
}); | ||
|
||
test('works with an array of booleans', () => { | ||
const input = [true, false, true, false, true]; | ||
const result = a_chunk(input, 2); | ||
expect(result).toEqual([[true, false], [true, false], [true]]); | ||
}); | ||
|
||
test('works with nested arrays as elements', () => { | ||
const input = [[1], [2], [3], [4]]; | ||
const result = a_chunk(input, 2); | ||
expect(result).toEqual([ | ||
[[1], [2]], | ||
[[3], [4]], | ||
]); | ||
}); | ||
|
||
test('handles chunk size of 1 on large input', () => { | ||
const input = [1, 2, 3, 4, 5, 6]; | ||
const result = a_chunk(input, 1); | ||
expect(result).toEqual([[1], [2], [3], [4], [5], [6]]); | ||
}); | ||
|
||
test('returns the input if chunk size is equal to input length', () => { | ||
const input = [10, 20, 30]; | ||
const result = a_chunk(input, 3); | ||
expect(result).toEqual([[10, 20, 30]]); | ||
}); | ||
|
||
test('works with chunk size of 2 on an empty array', () => { | ||
const input: number[] = []; | ||
const result = a_chunk(input, 2); | ||
expect(result).toEqual([]); | ||
}); | ||
|
||
test('handles large chunk size with large input', () => { | ||
const input = Array.from({ length: 20 }, (_, i) => i + 1); | ||
const result = a_chunk(input, 25); | ||
expect(result).toEqual([input]); // entire array as one chunk | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export function a_chunk<T>(input: T[], chunkSize: number): T[][] { | ||
const result: T[][] = []; | ||
|
||
for (let i = 0; i < input.length; i += chunkSize) { | ||
result.push(input.slice(i, i + chunkSize)); | ||
} | ||
|
||
return result; | ||
} |
115 changes: 115 additions & 0 deletions
115
libs/dfts-helper/src/lib/helper/array/hash/hash.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { a_hashFrom } from './hash'; | ||
|
||
describe('a_hashFrom', () => { | ||
test('returns first element if the string is empty', () => { | ||
const arr = ['a', 'b', 'c']; | ||
expect(a_hashFrom(arr, '')).toBe('a'); | ||
}); | ||
|
||
test('works with a single-character string', () => { | ||
const arr = ['x', 'y', 'z']; | ||
expect(a_hashFrom(arr, 'A')).toBeDefined(); | ||
}); | ||
|
||
test('works with a multi-character string', () => { | ||
const arr = ['apple', 'banana', 'cherry', 'date']; | ||
const result = a_hashFrom(arr, 'hello'); | ||
expect(arr).toContain(result); | ||
}); | ||
|
||
test('returns a consistent value for the same string', () => { | ||
const arr = [1, 2, 3, 4, 5]; | ||
const str = 'consistent'; | ||
const firstCall = a_hashFrom(arr, str); | ||
const secondCall = a_hashFrom(arr, str); | ||
expect(firstCall).toBe(secondCall); | ||
}); | ||
|
||
test('different strings should produce different (not necessarily unique) results', () => { | ||
const arr = [1, 2, 3, 4, 5]; | ||
const result1 = a_hashFrom(arr, 'abc'); | ||
const result2 = a_hashFrom(arr, 'abd'); | ||
// They might map to the same index by chance, but often won't. | ||
// This test just ensures the function runs without error. | ||
expect(arr).toContain(result1); | ||
expect(arr).toContain(result2); | ||
}); | ||
|
||
test('works with non-string array elements (numbers)', () => { | ||
const arr = [10, 20, 30]; | ||
const result = a_hashFrom(arr, 'test'); | ||
expect([10, 20, 30]).toContain(result); | ||
}); | ||
|
||
test('works with boolean elements', () => { | ||
const arr = [true, false]; | ||
const result = a_hashFrom(arr, 'true-or-false'); | ||
expect([true, false]).toContain(result); | ||
}); | ||
|
||
test('works with objects', () => { | ||
const arr = [{ id: 1 }, { id: 2 }, { id: 3 }]; | ||
const result = a_hashFrom(arr, 'object-test'); | ||
expect(arr).toContain(result); | ||
}); | ||
|
||
test('works with large arrays', () => { | ||
const arr = Array.from({ length: 100 }, (_, i) => i); | ||
const result = a_hashFrom(arr, 'large-array'); | ||
expect(arr).toContain(result); | ||
}); | ||
|
||
test('handles special characters in the string', () => { | ||
const arr = ['A', 'B', 'C', 'D']; | ||
const result = a_hashFrom(arr, '✨unicode✨'); | ||
expect(arr).toContain(result); | ||
}); | ||
|
||
test('handles strings that differ by only one character', () => { | ||
const arr = ['red', 'green', 'blue']; | ||
const result1 = a_hashFrom(arr, 'colorA'); | ||
const result2 = a_hashFrom(arr, 'colorB'); | ||
expect(arr).toContain(result1); | ||
expect(arr).toContain(result2); | ||
// Just ensuring both run without errors and produce valid outputs. | ||
}); | ||
|
||
test('works with numeric strings', () => { | ||
const arr = [null, 'second', 'third']; | ||
const result = a_hashFrom(arr, '12345'); | ||
expect([null, 'second', 'third']).toContain(result); | ||
}); | ||
|
||
test('works with very long strings', () => { | ||
const arr = ['first', 'second', 'third']; | ||
const longStr = 'a'.repeat(10_000); | ||
const result = a_hashFrom(arr, longStr); | ||
expect(arr).toContain(result); | ||
}); | ||
|
||
test('works with chunked strings', () => { | ||
const arr = ['first', 'second', 'third', 'fourth']; | ||
const str = 'abcd'.repeat(100); // a repeated pattern | ||
const result = a_hashFrom(arr, str); | ||
expect(arr).toContain(result); | ||
}); | ||
|
||
test('works with a single-element array', () => { | ||
const arr = [42]; | ||
const result = a_hashFrom(arr, 'anything'); | ||
expect(result).toBe(42); | ||
}); | ||
|
||
test('works with a prime-length array', () => { | ||
const arr = [true, false, null, undefined, 0, '', 'end']; | ||
// length: 7 (prime) | ||
const result = a_hashFrom(arr, 'prime-length-test'); | ||
expect(arr).toContain(result); | ||
}); | ||
|
||
test('handles an array of strings with repeated elements', () => { | ||
const arr = ['repeat', 'repeat', 'unique', 'repeat']; | ||
const result = a_hashFrom(arr, 'repetitive'); | ||
expect(arr).toContain(result); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export function a_hashFrom<T>(array: T[], str: string): T { | ||
const length = str.length; | ||
if (length === 0) return array[0]; | ||
|
||
let hash = 0; | ||
for (let i = 0; i < length; i++) { | ||
hash = (hash * 31 + str.charCodeAt(i)) >>> 0; | ||
} | ||
|
||
return array[hash % array.length]; | ||
} |