@stacksjs/arrays 0.64.6 → 0.67.0

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/src/contains.ts DELETED
@@ -1,87 +0,0 @@
1
- /**
2
- * Returns true if the needle is contained in the haystack.
3
- *
4
- * @param needle
5
- * @param haystack
6
- * @example
7
- * ```ts
8
- * contains('foo', ['foo', 'bar']) // true
9
- * contains('foo', ['bar']) // false
10
- * ```
11
- */
12
- export function contains(needle: string, haystack: string[]) {
13
- return haystack.some((hay) => needle.includes(hay))
14
- }
15
-
16
- /**
17
- * Returns true if all needles are contained in the haystack.
18
- * @param needles
19
- * @param haystack
20
- * @example
21
- * ```ts
22
- * containsAll(['foo', 'bar'], ['foo', 'bar', 'baz']) // true
23
- * containsAll(['foo', 'bar'], ['foo', 'baz']) // false
24
- * ```
25
- */
26
- export function containsAll(needles: string[], haystack: string[]) {
27
- return needles.every((needle) => contains(needle, haystack))
28
- }
29
-
30
- /**
31
- * Returns true if any needle is contained in the haystack.
32
- * @param needles
33
- * @param haystack
34
- * @example
35
- * ```ts
36
- * containsAny(['foo', 'bar'], ['foo', 'bar', 'baz']) // true
37
- * containsAny(['foo', 'bar'], ['foo', 'baz']) // true
38
- * containsAny(['foo', 'bar'], ['baz']) // false
39
- * ```
40
- */
41
- export function containsAny(needles: string[], haystack: string[]) {
42
- return needles.some((needle) => contains(needle, haystack))
43
- }
44
-
45
- /**
46
- * Returns true if none of the needles are contained in the haystack.
47
- * @param needles
48
- * @param haystack
49
- * @example
50
- * ```ts
51
- * containsNone(['foo', 'bar'], ['foo', 'bar', 'baz']) // false
52
- * containsNone(['foo', 'bar'], ['foo', 'baz']) // false
53
- * containsNone(['foo', 'bar'], ['baz']) // true
54
- * ```
55
- */
56
- export function containsNone(needles: string[], haystack: string[]) {
57
- return !containsAny(needles, haystack)
58
- }
59
-
60
- /**
61
- * Returns true if all needles are contained in the haystack.
62
- * @param needles
63
- * @param haystack
64
- * @example
65
- * ```ts
66
- * containsOnly(['foo', 'bar'], ['foo', 'bar', 'baz']) // false
67
- * containsOnly(['foo', 'bar'], ['foo', 'baz']) // false
68
- * containsOnly(['foo', 'bar'], ['foo', 'bar']) // true
69
- * ```
70
- */
71
- export function containsOnly(needles: string[], haystack: string[]) {
72
- return containsAll(haystack, needles)
73
- }
74
-
75
- /**
76
- * Returns true if the needle is not contained in the haystack.
77
- * @param needle
78
- * @param haystack
79
- * @example
80
- * ```ts
81
- * doesNotContain('foo', ['foo', 'bar']) // false
82
- * doesNotContain('foo', ['bar']) // true
83
- * ```
84
- */
85
- export function doesNotContain(needle: string, haystack: string[]) {
86
- return !contains(needle, haystack)
87
- }
package/src/helpers.ts DELETED
@@ -1,293 +0,0 @@
1
- import type { Arrayable, Nullable } from '@stacksjs/types'
2
- import { clamp } from '@stacksjs/utils'
3
-
4
- /**
5
- * Convert `Arrayable<T>` to `Array<T>`
6
- *
7
- * @category Array
8
- * @example
9
- * ```ts
10
- * toArray('foo') // ['foo']
11
- * toArray(['foo']) // ['foo']
12
- * toArray(null) // []
13
- * toArray(undefined) // []
14
- * toArray(1) // [1]
15
- * toArray([1]) // [1]
16
- * toArray({ foo: 'bar' }) // [{ foo: 'bar' }]
17
- * toArray([{ foo: 'bar' }]) // [{ foo: 'bar' }]
18
- * ```
19
- */
20
- export function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {
21
- array = array ?? []
22
- return Array.isArray(array) ? array : [array]
23
- }
24
-
25
- /**
26
- * Flatten `Arrayable<T>` to `Array<T>`
27
- *
28
- * @category Array
29
- * @example
30
- * ```ts
31
- * flatten([1, [2, [3, [4, [5]]]]]) // [1, 2, 3, 4, 5]
32
- * ```
33
- */
34
- export function flatten<T>(array?: Nullable<Arrayable<T | Array<T>>>): Array<T> {
35
- return toArray(array).flat(1) as Array<T>
36
- }
37
-
38
- /**
39
- * Use rest arguments to merge arrays
40
- *
41
- * @category Array
42
- * @example
43
- * ```ts
44
- * mergeArrayable([1, 2], [3, 4], [5, 6]) // [1, 2, 3, 4, 5, 6]
45
- * ```
46
- */
47
- export function mergeArrayable<T>(...args: Nullable<Arrayable<T>>[]): Array<T> {
48
- return args.flatMap((i) => toArray(i))
49
- }
50
-
51
- export type PartitionFilter<T> = (i: T, idx: number, arr: readonly T[]) => any
52
-
53
- /**
54
- * Divide an array into two parts by a filter function
55
- *
56
- * @category Array
57
- * @example
58
- * ```ts
59
- * const [odd, even] = partition([1, 2, 3, 4], i => i % 2 != 0)
60
- * console.log(odd) // [1, 3]
61
- * console.log(even) // [2, 4]
62
- * ```
63
- */
64
- export function partition<T>(array: readonly T[], f1: PartitionFilter<T>): [T[], T[]]
65
- export function partition<T>(array: readonly T[], f1: PartitionFilter<T>, f2: PartitionFilter<T>): [T[], T[], T[]]
66
- export function partition<T>(
67
- array: readonly T[],
68
- f1: PartitionFilter<T>,
69
- f2: PartitionFilter<T>,
70
- f3: PartitionFilter<T>,
71
- ): [T[], T[], T[], T[]]
72
- export function partition<T>(
73
- array: readonly T[],
74
- f1: PartitionFilter<T>,
75
- f2: PartitionFilter<T>,
76
- f3: PartitionFilter<T>,
77
- f4: PartitionFilter<T>,
78
- ): [T[], T[], T[], T[], T[]]
79
- export function partition<T>(
80
- array: readonly T[],
81
- f1: PartitionFilter<T>,
82
- f2: PartitionFilter<T>,
83
- f3: PartitionFilter<T>,
84
- f4: PartitionFilter<T>,
85
- f5: PartitionFilter<T>,
86
- ): [T[], T[], T[], T[], T[], T[]]
87
- export function partition<T>(
88
- array: readonly T[],
89
- f1: PartitionFilter<T>,
90
- f2: PartitionFilter<T>,
91
- f3: PartitionFilter<T>,
92
- f4: PartitionFilter<T>,
93
- f5: PartitionFilter<T>,
94
- f6: PartitionFilter<T>,
95
- ): [T[], T[], T[], T[], T[], T[], T[]]
96
- export function partition<T>(array: readonly T[], ...filters: PartitionFilter<T>[]): any {
97
- const result: T[][] = Array.from({ length: filters.length + 1 })
98
- .fill(null)
99
- .map(() => [])
100
-
101
- array.forEach((e, idx, arr) => {
102
- let i = 0
103
- for (const filter of filters) {
104
- if (filter(e, idx, arr)) {
105
- ;(result[i] as T[]).push(e)
106
- return
107
- }
108
- i += 1
109
- }
110
- ;(result[i] as T[]).push(e)
111
- })
112
- return result
113
- }
114
-
115
- /**
116
- * Unique an Array
117
- *
118
- * @category Array
119
- * @example
120
- * ```ts
121
- * uniq([1, 2, 3, 3, 2, 1]) // [1, 2, 3]
122
- * ```
123
- */
124
- export function uniq<T>(array: readonly T[]): T[] {
125
- return Array.from(new Set(array))
126
- }
127
-
128
- /**
129
- * Unique an Array
130
- *
131
- * @param array
132
- * @example
133
- * ```ts
134
- * unique([1, 2, 3, 3, 2, 1]) // [1, 2, 3]
135
- * ```
136
- */
137
- export function unique<T>(array: readonly T[]): T[] {
138
- return uniq(array)
139
- }
140
-
141
- /**
142
- * Unique an Array by a custom equality function
143
- *
144
- * @category Array
145
- * @example
146
- * ```ts
147
- * uniqueBy([1, 2, 3, 3, 2, 1], (a, b) => a === b) // [1, 2, 3]
148
- * ```
149
- */
150
- export function uniqueBy<T>(array: readonly T[], equalFn: (a: any, b: any) => boolean): T[] {
151
- return array.reduce((acc: T[], cur: any) => {
152
- const index = acc.findIndex((item: any) => equalFn(cur, item))
153
- if (index === -1) acc.push(cur)
154
- return acc
155
- }, [])
156
- }
157
-
158
- /**
159
- * Get last item
160
- *
161
- * @category Array
162
- * @example
163
- * ```ts
164
- * last([1, 2, 3]) // 3
165
- * ```
166
- */
167
- export function last(array: readonly []): undefined
168
- export function last<T>(array: readonly T[]): T
169
- export function last<T>(array: readonly T[]): T | undefined {
170
- return at(array, -1)
171
- }
172
-
173
- /**
174
- * Remove an item from Array
175
- *
176
- * @category Array
177
- * @example
178
- * ```ts
179
- * const arr = [1, 2, 3]
180
- * remove(arr, 2) // true
181
- * Arr.remove(arr, 4) // false
182
- * console.log(arr) // [1, 3]
183
- */
184
- export function remove<T>(array: T[], value: T) {
185
- if (!array) return false
186
-
187
- const index = array.indexOf(value)
188
- if (index >= 0) {
189
- array.splice(index, 1)
190
- return true
191
- }
192
-
193
- return false
194
- }
195
-
196
- /**
197
- * Get nth item of Array. Negative for backward
198
- *
199
- * @category Array
200
- * @example
201
- * ```ts
202
- * at([1, 2, 3], 1) // 2
203
- * at([1, 2, 3], -1) // 3
204
- * at([1, 2, 3], 3) // undefined
205
- * at([1, 2, 3], -4) // undefined
206
- * ```
207
- */
208
- export function at(array: readonly [], index: number): undefined
209
- export function at<T>(array: readonly T[], index: number): T
210
- export function at<T>(array: readonly T[] | [], index: number): T | undefined {
211
- const len = array.length
212
- if (!len) return undefined
213
-
214
- if (index < 0) index += len
215
-
216
- return array[index]
217
- }
218
-
219
- /**
220
- * Move an item from one index to another
221
- * @param array
222
- * @param from
223
- * @param to
224
- *
225
- * @category Array
226
- * @example
227
- * ```ts
228
- * move([1, 2, 3, 4], 0, 2) // [2, 3, 1, 4]
229
- * move([1, 2, 3, 4], 0, -1) // [2, 3, 4, 1]
230
- * move([1, 2, 3, 4], -1, 0) // [4, 1, 2, 3]
231
- * move([1, 2, 3, 4], -1, -2) // [1, 4, 2, 3]
232
- * move([1, 2, 3, 4], 1, 1) // [1, 2, 3, 4]
233
- * ```
234
- */
235
- export function move<T>(array: T[], from: number, to: number): T[] {
236
- const len = array.length
237
- if (!len) return []
238
-
239
- if (from < 0) from += len
240
-
241
- if (to < 0) to += len
242
-
243
- const item = array.splice(from, 1)[0]
244
- array.splice(to, 0, item as T)
245
- return array
246
- }
247
-
248
- /**
249
- * Clamp a number to the index range of an array.
250
- *
251
- * @category Array
252
- * @example
253
- * ```ts
254
- * clampArrayRange([1, 2, 3], 0) // 0
255
- * clampArrayRange([1, 2, 3], 1) // 1
256
- * clampArrayRange([1, 2, 3], 2) // 2
257
- * clampArrayRange([1, 2, 3], 3) // 2
258
- * clampArrayRange([1, 2, 3], 4) // 2
259
- * clampArrayRange([1, 2, 3], -1) // 0
260
- */
261
- export function clampArrayRange(arr: readonly unknown[], n: number) {
262
- return clamp(n, 0, arr.length - 1)
263
- }
264
-
265
- /**
266
- * Get random items from an array
267
- *
268
- * @category Array
269
- * @example
270
- * ```ts
271
- * sample([1, 2, 3, 4], 2) // [2, 3]
272
- * ```
273
- */
274
- export function sample<T>(arr: T[], count: number) {
275
- return Array.from({ length: count }, (_) => arr[Math.round(Math.random() * (arr.length - 1))])
276
- }
277
-
278
- /**
279
- * Shuffle an array. This function mutates the array.
280
- *
281
- * @category Array
282
- * @example
283
- * ```ts
284
- * shuffle([1, 2, 3, 4]) // [2, 4, 1, 3]
285
- * ```
286
- */
287
- export function shuffle<T>(array: T[]): T[] {
288
- for (let i = array.length - 1; i > 0; i--) {
289
- const j = Math.floor(Math.random() * (i + 1))
290
- ;[array[i] as T, array[j] as T] = [array[j] as T, array[i] as T]
291
- }
292
- return array
293
- }
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from './arr'
2
- export * as arr from './arr'
3
- export * from './macro'
package/src/macro.ts DELETED
@@ -1,149 +0,0 @@
1
- import type { Arrayable, Nullable } from '@stacksjs/types'
2
- import { contains, containsAll, containsAny, containsNone, containsOnly, doesNotContain } from './contains'
3
- import type { PartitionFilter } from './helpers'
4
- import {
5
- at,
6
- clampArrayRange,
7
- flatten,
8
- last,
9
- mergeArrayable,
10
- move,
11
- partition,
12
- remove,
13
- sample,
14
- shuffle,
15
- toArray,
16
- uniq,
17
- uniqueBy,
18
- } from './helpers'
19
- import { average, median, mode, range, sum } from './math'
20
-
21
- export const Arr = {
22
- contains(needle: string, haystack: string[]) {
23
- return contains(needle, haystack)
24
- },
25
-
26
- containsAll(needles: string[], haystack: string[]) {
27
- return containsAll(needles, haystack)
28
- },
29
-
30
- containsAny(needles: string[], haystack: string[]) {
31
- return containsAny(needles, haystack)
32
- },
33
-
34
- containsNone(needles: string[], haystack: string[]) {
35
- return containsNone(needles, haystack)
36
- },
37
-
38
- containsOnly(needles: string[], haystack: string[]) {
39
- return containsOnly(needles, haystack)
40
- },
41
-
42
- doesNotContain(needle: string, haystack: string[]) {
43
- return doesNotContain(needle, haystack)
44
- },
45
-
46
- toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {
47
- return toArray(array)
48
- },
49
-
50
- flatten<T>(array?: Nullable<Arrayable<T | Array<T>>>): Array<T> {
51
- return flatten(array)
52
- },
53
-
54
- mergeArrayable<T>(...args: Nullable<Arrayable<T>>[]): Array<T> {
55
- return mergeArrayable(...args)
56
- },
57
-
58
- partition<T>(array: readonly T[], filter: PartitionFilter<T>): [T[], T[]] {
59
- return partition(array, filter)
60
- },
61
-
62
- /**
63
- * Returns a random item/s from the array
64
- */
65
- random<T>(arr: T[], count = 1): T[] {
66
- return sample(arr, count).filter((item): item is T => item != null)
67
- },
68
-
69
- /**
70
- * Returns random item/s from the array
71
- */
72
- sample<T>(arr: T[], count = 1): T[] {
73
- // Get the sample array (may contain undefined values)
74
- const sampleArr = sample(arr, count)
75
-
76
- // Filter out any undefined values
77
- return sampleArr.filter((item): item is T => item !== undefined)
78
- },
79
-
80
- unique<T>(arr: T[]): T[] {
81
- return uniq(arr)
82
- },
83
-
84
- uniqueBy<T>(arr: readonly T[], equalFn: (a: any, b: any) => boolean): T[] {
85
- return uniqueBy(arr, equalFn)
86
- },
87
-
88
- last<T>(arr: T[]): T | undefined {
89
- return last(arr)
90
- },
91
-
92
- remove<T>(arr: T[], value: T) {
93
- return remove(arr, value)
94
- },
95
-
96
- at(arr: any[], index: number): any {
97
- return at(arr, index)
98
- },
99
-
100
- range(arr: readonly number[]): number {
101
- return range(arr)
102
- },
103
-
104
- move<T>(arr: T[], from: number, to: number): T[] {
105
- return move(arr, from, to)
106
- },
107
-
108
- clampArrayRange(arr: readonly unknown[], n: number) {
109
- return clampArrayRange(arr, n)
110
- },
111
-
112
- shuffle<T>(arr: T[]): T[] {
113
- return shuffle(arr)
114
- },
115
-
116
- /**
117
- * Returns the sum of all items in the array
118
- */
119
- sum(arr: number[]): number {
120
- return sum(arr)
121
- },
122
-
123
- /**
124
- * Returns the average of all items in the array
125
- */
126
- average(arr: number[]): number {
127
- return average(arr)
128
- },
129
-
130
- avg(arr: number[]): number {
131
- return average(arr)
132
- },
133
-
134
- /**
135
- * Returns the median of all items in the array
136
- */
137
- median(arr: number[]): number {
138
- return median(arr)
139
- },
140
-
141
- /**
142
- * Returns the mode of all items in the array
143
- */
144
- mode(arr: number[]): number {
145
- return mode(arr)
146
- },
147
- }
148
-
149
- export const arr = Arr