@gesslar/toolkit 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +1 -0
- package/src/lib/Collection.js +108 -0
- package/src/types/Collection.d.ts +138 -0
- package/src/types/index.d.ts +1 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export {default as FS} from "./lib/FS.js"
|
|
|
5
5
|
|
|
6
6
|
// Utility classes
|
|
7
7
|
export {default as Cache} from "./lib/Cache.js"
|
|
8
|
+
export {default as Collection} from "./lib/Collection.js"
|
|
8
9
|
export {default as Data} from "./lib/Data.js"
|
|
9
10
|
export {default as Glog} from "./lib/Glog.js"
|
|
10
11
|
export {default as Sass} from "./lib/Sass.js"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import Data from "./Data.js"
|
|
2
|
+
import Valid from "./Valid.js"
|
|
3
|
+
|
|
4
|
+
export default class Collection {
|
|
5
|
+
static evalArray(collection, predicate, forward=true) {
|
|
6
|
+
const req = "Array"
|
|
7
|
+
const type = Data.typeOf(collection)
|
|
8
|
+
|
|
9
|
+
Valid.type(collection, req, `Invalid collection. Expected '${req}, got ${type}`)
|
|
10
|
+
Valid.type(predicate, "Function",
|
|
11
|
+
`Invalid predicate, expected 'Function', got ${Data.typeOf(predicate)}`)
|
|
12
|
+
|
|
13
|
+
const work = forward
|
|
14
|
+
? Array.from(collection)
|
|
15
|
+
: Array.from(collection).toReversed()
|
|
16
|
+
|
|
17
|
+
for(let i = 0; i < work.length; i++) {
|
|
18
|
+
const result = predicate(work[i], i, collection) ?? null
|
|
19
|
+
|
|
20
|
+
if(result)
|
|
21
|
+
return result
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static evalObject(collection, predicate) {
|
|
26
|
+
const req = "Object"
|
|
27
|
+
const type = Data.typeOf(collection)
|
|
28
|
+
|
|
29
|
+
Valid.type(collection, req, `Invalid collection. Expected '${req}, got ${type}`)
|
|
30
|
+
Valid.type(predicate, "Function",
|
|
31
|
+
`Invalid predicate, expected 'Function', got ${Data.typeOf(predicate)}`)
|
|
32
|
+
|
|
33
|
+
const work = Object.entries(collection)
|
|
34
|
+
|
|
35
|
+
for(let i = 0; i < work.length; i++) {
|
|
36
|
+
const result = predicate(work[i][1], work[i][0], collection)
|
|
37
|
+
|
|
38
|
+
if(result)
|
|
39
|
+
return result
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static evalSet(collection, predicate) {
|
|
44
|
+
const req = "Set"
|
|
45
|
+
const type = Data.typeOf(collection)
|
|
46
|
+
|
|
47
|
+
Valid.type(collection, req, `Invalid collection. Expected '${req}, got ${type}`)
|
|
48
|
+
Valid.type(predicate, "Function",
|
|
49
|
+
`Invalid predicate, expected 'Function', got ${Data.typeOf(predicate)}`)
|
|
50
|
+
|
|
51
|
+
const work = Array.from(collection)
|
|
52
|
+
|
|
53
|
+
for(let i = 0; i < work.length; i++) {
|
|
54
|
+
const result = predicate(work[i], collection)
|
|
55
|
+
|
|
56
|
+
if(result)
|
|
57
|
+
return result
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static evalMap(collection, predicate, forward=true) {
|
|
62
|
+
const req = "Map"
|
|
63
|
+
const type = Data.typeOf(collection)
|
|
64
|
+
|
|
65
|
+
Valid.type(collection, req, `Invalid collection. Expected '${req}, got ${type}`)
|
|
66
|
+
Valid.type(predicate, "Function",
|
|
67
|
+
`Invalid predicate, expected 'Function', got ${Data.typeOf(predicate)}`)
|
|
68
|
+
|
|
69
|
+
const work = forward
|
|
70
|
+
? Array.from(collection)
|
|
71
|
+
: Array.from(collection).toReversed()
|
|
72
|
+
|
|
73
|
+
for(let i = 0; i < work.length; i++) {
|
|
74
|
+
const result = predicate(work[i][1], work[i][0], collection) ?? null
|
|
75
|
+
|
|
76
|
+
if(result)
|
|
77
|
+
return result
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static zip(array1, array2) {
|
|
82
|
+
const minLength = Math.min(array1.length, array2.length)
|
|
83
|
+
|
|
84
|
+
return Array.from({length: minLength}, (_, i) => [array1[i], array2[i]])
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static unzip(array) {
|
|
88
|
+
if(!Array.isArray(array) || array.length === 0) {
|
|
89
|
+
return [] // Handle empty or invalid input
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Determine the number of "unzipped" arrays needed
|
|
93
|
+
// This assumes all inner arrays have the same length, or we take the max length
|
|
94
|
+
const numUnzippedArrays = Math.max(...array.map(arr => arr.length))
|
|
95
|
+
|
|
96
|
+
// Initialize an array of empty arrays to hold the unzipped results
|
|
97
|
+
const unzipped = Array.from({length: numUnzippedArrays}, () => [])
|
|
98
|
+
|
|
99
|
+
// Iterate through the zipped array and populate the unzipped arrays
|
|
100
|
+
for(let i = 0; i < array.length; i++) {
|
|
101
|
+
for(let j = 0; j < numUnzippedArrays; j++) {
|
|
102
|
+
unzipped[j].push(array[i][j])
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return unzipped
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Implementation: ../lib/Collection.js
|
|
2
|
+
// Type definitions for Collection utilities
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Collection utility functions for evaluating and manipulating arrays, objects, sets, and maps.
|
|
6
|
+
* Provides functional programming patterns for collection processing with consistent error handling.
|
|
7
|
+
*/
|
|
8
|
+
export default class Collection {
|
|
9
|
+
/**
|
|
10
|
+
* Evaluates an array with a predicate function, returning the first truthy result.
|
|
11
|
+
*
|
|
12
|
+
* @param collection - The array to evaluate
|
|
13
|
+
* @param predicate - Function called for each element: (element, index, array) => result
|
|
14
|
+
* @param forward - Whether to iterate forward (true) or backward (false). Default: true
|
|
15
|
+
* @returns The first truthy result from the predicate, or undefined if none found
|
|
16
|
+
*
|
|
17
|
+
* @throws {Sass} If collection is not an Array or predicate is not a Function
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
22
|
+
*
|
|
23
|
+
* const numbers = [1, 2, 3, 4, 5]
|
|
24
|
+
* const result = Collection.evalArray(numbers, (n, i) => n > 3 ? n * 2 : null)
|
|
25
|
+
* console.log(result) // 8 (first element > 3, doubled)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
static evalArray<T, R>(
|
|
29
|
+
collection: T[],
|
|
30
|
+
predicate: (element: T, index: number, array: T[]) => R | null | undefined,
|
|
31
|
+
forward?: boolean
|
|
32
|
+
): R | undefined
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Evaluates an object with a predicate function, returning the first truthy result.
|
|
36
|
+
*
|
|
37
|
+
* @param collection - The object to evaluate
|
|
38
|
+
* @param predicate - Function called for each property: (value, key, object) => result
|
|
39
|
+
* @returns The first truthy result from the predicate, or undefined if none found
|
|
40
|
+
*
|
|
41
|
+
* @throws {Sass} If collection is not an Object or predicate is not a Function
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
46
|
+
*
|
|
47
|
+
* const obj = {a: 1, b: 2, c: 3}
|
|
48
|
+
* const result = Collection.evalObject(obj, (value, key) => value > 2 ? `${key}:${value}` : null)
|
|
49
|
+
* console.log(result) // "c:3"
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
static evalObject<T, R>(
|
|
53
|
+
collection: Record<string, T>,
|
|
54
|
+
predicate: (value: T, key: string, object: Record<string, T>) => R | null | undefined
|
|
55
|
+
): R | undefined
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Evaluates a Set with a predicate function, returning the first truthy result.
|
|
59
|
+
*
|
|
60
|
+
* @param collection - The Set to evaluate
|
|
61
|
+
* @param predicate - Function called for each element: (element, set) => result
|
|
62
|
+
* @returns The first truthy result from the predicate, or undefined if none found
|
|
63
|
+
*
|
|
64
|
+
* @throws {Sass} If collection is not a Set or predicate is not a Function
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
69
|
+
*
|
|
70
|
+
* const set = new Set([1, 2, 3, 4, 5])
|
|
71
|
+
* const result = Collection.evalSet(set, (n, s) => n > 3 ? n * 2 : null)
|
|
72
|
+
* console.log(result) // 8
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
static evalSet<T, R>(
|
|
76
|
+
collection: Set<T>,
|
|
77
|
+
predicate: (element: T, set: Set<T>) => R | null | undefined
|
|
78
|
+
): R | undefined
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Evaluates a Map with a predicate function, returning the first truthy result.
|
|
82
|
+
*
|
|
83
|
+
* @param collection - The Map to evaluate
|
|
84
|
+
* @param predicate - Function called for each entry: (value, key, map) => result
|
|
85
|
+
* @param forward - Whether to iterate forward (true) or backward (false). Default: true
|
|
86
|
+
* @returns The first truthy result from the predicate, or undefined if none found
|
|
87
|
+
*
|
|
88
|
+
* @throws {Sass} If collection is not a Map or predicate is not a Function
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
93
|
+
*
|
|
94
|
+
* const map = new Map([['a', 1], ['b', 2], ['c', 3]])
|
|
95
|
+
* const result = Collection.evalMap(map, (value, key) => value > 2 ? `${key}:${value}` : null)
|
|
96
|
+
* console.log(result) // "c:3"
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
static evalMap<K, V, R>(
|
|
100
|
+
collection: Map<K, V>,
|
|
101
|
+
predicate: (value: V, key: K, map: Map<K, V>) => R | null | undefined,
|
|
102
|
+
forward?: boolean
|
|
103
|
+
): R | undefined
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Zips two arrays together into an array of pairs.
|
|
107
|
+
*
|
|
108
|
+
* @param array1 - The first array
|
|
109
|
+
* @param array2 - The second array
|
|
110
|
+
* @returns Array of [element1, element2] pairs, length of shorter input array
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
115
|
+
*
|
|
116
|
+
* const result = Collection.zip([1, 2, 3], ['a', 'b', 'c'])
|
|
117
|
+
* console.log(result) // [[1, 'a'], [2, 'b'], [3, 'c']]
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
static zip<T, U>(array1: T[], array2: U[]): [T, U][]
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Unzips an array of arrays into separate arrays.
|
|
124
|
+
*
|
|
125
|
+
* @param array - Array of arrays to unzip
|
|
126
|
+
* @returns Array of separate arrays, one for each position
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
131
|
+
*
|
|
132
|
+
* const zipped = [[1, 'a'], [2, 'b'], [3, 'c']]
|
|
133
|
+
* const result = Collection.unzip(zipped)
|
|
134
|
+
* console.log(result) // [[1, 2, 3], ['a', 'b', 'c']]
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
static unzip<T>(array: T[][]): T[][]
|
|
138
|
+
}
|
package/src/types/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { default as FS } from './FS.js'
|
|
|
6
6
|
|
|
7
7
|
// Utility classes
|
|
8
8
|
export { default as Cache } from './Cache.js'
|
|
9
|
+
export { default as Collection } from './Collection.js'
|
|
9
10
|
export { default as Data } from './Data.js'
|
|
10
11
|
export { default as Glog } from './Glog.js'
|
|
11
12
|
export { default as Sass } from './Sass.js'
|