@stacksjs/arrays 0.65.0 → 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/dist/index.js +1 -4
- package/package.json +4 -6
- package/dist/index.js.map +0 -13
- package/src/arr.ts +0 -3
- package/src/contains.ts +0 -87
- package/src/helpers.ts +0 -300
- package/src/index.ts +0 -3
- package/src/macro.ts +0 -145
- package/src/math.ts +0 -245
package/dist/index.js
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var v=Object.defineProperty;var h=(z,E)=>{for(var G in E)v(z,G,{get:E[G],enumerable:!0,configurable:!0,set:(H)=>E[G]=()=>H})};var f={};h(f,{zScore:()=>i,variance:()=>x,uniqueBy:()=>C,unique:()=>u,uniq:()=>Y,toArray:()=>P,sum:()=>$,standardDeviation:()=>g,shuffle:()=>w,sample:()=>_,remove:()=>F,range:()=>b,product:()=>d,percentile:()=>c,partition:()=>j,move:()=>N,mode:()=>q,min:()=>p,mergeArrayable:()=>T,median:()=>Q,max:()=>A,last:()=>V,interquartileRange:()=>l,flatten:()=>X,doesNotContain:()=>S,covariance:()=>s,containsOnly:()=>O,containsNone:()=>D,containsAny:()=>W,containsAll:()=>U,contains:()=>M,clampArrayRange:()=>R,avg:()=>o,average:()=>J,at:()=>Z});function M(z,E){return E.some((G)=>z.includes(G))}function U(z,E){return z.every((G)=>M(G,E))}function W(z,E){return z.some((G)=>M(G,E))}function D(z,E){return!W(z,E)}function O(z,E){return U(E,z)}function S(z,E){return!M(z,E)}import{clamp as m}from"@stacksjs/utils";function P(z){return z=z??[],Array.isArray(z)?z:[z]}function X(z){return P(z).reduce((E,G)=>E.concat(Array.isArray(G)?X(G):G),[])}function T(...z){return z.flatMap((E)=>P(E))}function j(z,...E){
|
|
3
|
-
|
|
4
|
-
//# debugId=B6B872CC06F3654D64756E2164756E21
|
|
5
|
-
//# sourceMappingURL=index.js.map
|
|
2
|
+
var v=Object.defineProperty;var h=(z,E)=>{for(var G in E)v(z,G,{get:E[G],enumerable:!0,configurable:!0,set:(H)=>E[G]=()=>H})};var f={};h(f,{zScore:()=>i,variance:()=>x,uniqueBy:()=>C,unique:()=>u,uniq:()=>Y,toArray:()=>P,sum:()=>$,standardDeviation:()=>g,shuffle:()=>w,sample:()=>_,remove:()=>F,range:()=>b,product:()=>d,percentile:()=>c,partition:()=>j,move:()=>N,mode:()=>q,min:()=>p,mergeArrayable:()=>T,median:()=>Q,max:()=>A,last:()=>V,interquartileRange:()=>l,flatten:()=>X,doesNotContain:()=>S,covariance:()=>s,containsOnly:()=>O,containsNone:()=>D,containsAny:()=>W,containsAll:()=>U,contains:()=>M,clampArrayRange:()=>R,avg:()=>o,average:()=>J,at:()=>Z});function M(z,E){return E.some((G)=>z.includes(G))}function U(z,E){return z.every((G)=>M(G,E))}function W(z,E){return z.some((G)=>M(G,E))}function D(z,E){return!W(z,E)}function O(z,E){return U(E,z)}function S(z,E){return!M(z,E)}import{clamp as m}from"@stacksjs/utils";function P(z){return z=z??[],Array.isArray(z)?z:[z]}function X(z){return P(z).reduce((E,G)=>E.concat(Array.isArray(G)?X(G):G),[])}function T(...z){return z.flatMap((E)=>P(E))}function j(z,...E){let G=Array.from({length:E.length+1}).fill(null).map(()=>[]);return z.forEach((H,I,K)=>{let L=0;for(let B of E){if(B(H,I,K)){G[L].push(H);return}L+=1}G[L].push(H)}),G}function Y(z){return Array.from(new Set(z))}function u(z){return Y(z)}function C(z,E){return z.reduce((G,H)=>{if(G.findIndex((K)=>E(H,K))===-1)G.push(H);return G},[])}function V(z){return Z(z,-1)}function F(z,E){if(!z)return!1;let G=z.indexOf(E);if(G>=0)return z.splice(G,1),!0;return!1}function Z(z,E){let G=z.length;if(!G)return;if(E<0)E+=G;return z[E]}function N(z,E,G){let H=z.length;if(!H)return[];if(E<0)E+=H;if(G<0)G+=H;let I=z.splice(E,1)[0];return z.splice(G,0,I),z}function R(z,E){return m(E,0,z.length-1)}function _(z,E){return Array.from({length:E},()=>z[Math.floor(Math.random()*z.length)])}function w(z){for(let E=z.length-1;E>0;E--){let G=Math.floor(Math.random()*(E+1));[z[E],z[G]]=[z[G],z[E]]}return z}function J(z){return $(z)/z.length}function o(z){return J(z)}function Q(z){if(z.length===0)throw new Error("Cannot compute median of an empty array");let E=[...z].sort((I,K)=>I-K),G=Math.floor(E.length/2),H;if(E.length%2!==0)H=E[G];else H=(E[G]+E[G-1])/2;return H}function q(z){return z.sort((E,G)=>z.filter((H)=>H===E).length-z.filter((H)=>H===G).length).pop()}function $(z){return z.reduce((E,G)=>E+G,0)}function d(z){return z.reduce((E,G)=>E*G,1)}function p(z){return Math.min(...z)}function A(z){return Math.max(...z)}function b(z){return A(z)-p(z)}function x(z){let E=J(z);return J(z.map((G)=>(G-E)**2))}function g(z){return Math.sqrt(x(z))}function i(z,E){return(E-J(z))/g(z)}function c(z,E){let G=[...z].sort((B,k)=>B-k),H=E/100*(G.length-1),I=Math.floor(H),K=Math.ceil(H),L=H-I;if(K===I)return G[H]??0;return(1-L)*(G[I]??0)+L*(G[K]??0)}function l(z){let E=Q(z.slice(0,Math.floor(z.length/2)));return Q(z.slice(Math.ceil(z.length/2)))-E}function s(z,E){if(z.length!==E.length)throw new Error("Arrays must have the same length");let G=J(z),H=J(E);return J(z.map((I,K)=>(I-G)*(E[K]-H)))}var Jz={contains(z,E){return M(z,E)},containsAll(z,E){return U(z,E)},containsAny(z,E){return W(z,E)},containsNone(z,E){return D(z,E)},containsOnly(z,E){return O(z,E)},doesNotContain(z,E){return S(z,E)},toArray(z){return P(z)},flatten(z){return X(z)},mergeArrayable(...z){return T(...z)},partition(z,E){return j(z,E)},random(z,E=1){return _(z,E).filter((G)=>G!=null)},sample(z,E=1){return _(z,E)},unique(z){return Y(z)},uniqueBy(z,E){return C(z,E)},last(z){return V(z)},remove(z,E){return F(z,E)},at(z,E){return Z(z,E)},range(z){return b(z)},move(z,E,G){return N(z,E,G)},clampArrayRange(z,E){return R(z,E)},shuffle(z){return w(z)},sum(z){return $(z)},average(z){return J(z)},avg(z){return J(z)},median(z){return Q(z)},mode(z){return q(z)}};export{i as zScore,x as variance,C as uniqueBy,u as unique,Y as uniq,P as toArray,$ as sum,g as standardDeviation,w as shuffle,_ as sample,F as remove,b as range,d as product,c as percentile,j as partition,N as move,q as mode,p as min,T as mergeArrayable,Q as median,A as max,V as last,l as interquartileRange,X as flatten,S as doesNotContain,s as covariance,O as containsOnly,D as containsNone,W as containsAny,U as containsAll,M as contains,R as clampArrayRange,o as avg,J as average,Z as at,f as arr,Jz as Arr};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/arrays",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.67.0",
|
|
5
5
|
"description": "The Stacks array utilities.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
7
|
"contributors": ["Chris Breuer <chris@stacksjs.org>"],
|
|
@@ -26,17 +26,15 @@
|
|
|
26
26
|
],
|
|
27
27
|
"exports": {
|
|
28
28
|
".": {
|
|
29
|
-
"bun": "./src/index.ts",
|
|
30
29
|
"import": "./dist/index.js"
|
|
31
30
|
},
|
|
32
31
|
"./*": {
|
|
33
|
-
"bun": "./src/*",
|
|
34
32
|
"import": "./dist/*"
|
|
35
33
|
}
|
|
36
34
|
},
|
|
37
35
|
"module": "dist/index.js",
|
|
38
36
|
"types": "dist/index.d.ts",
|
|
39
|
-
"files": ["README.md", "dist"
|
|
37
|
+
"files": ["README.md", "dist"],
|
|
40
38
|
"scripts": {
|
|
41
39
|
"build": "bun build.ts",
|
|
42
40
|
"typecheck": "bun tsc --noEmit",
|
|
@@ -44,9 +42,9 @@
|
|
|
44
42
|
"prepublishOnly": "bun run build"
|
|
45
43
|
},
|
|
46
44
|
"dependencies": {
|
|
47
|
-
"@stacksjs/utils": "0.
|
|
45
|
+
"@stacksjs/utils": "0.67.0"
|
|
48
46
|
},
|
|
49
47
|
"devDependencies": {
|
|
50
|
-
"@stacksjs/development": "0.
|
|
48
|
+
"@stacksjs/development": "0.67.0"
|
|
51
49
|
}
|
|
52
50
|
}
|
package/dist/index.js.map
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/contains.ts", "../src/helpers.ts", "../src/math.ts", "../src/macro.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Returns true if the needle is contained in the haystack.\n *\n * @param needle\n * @param haystack\n * @example\n * ```ts\n * contains('foo', ['foo', 'bar']) // true\n * contains('foo', ['bar']) // false\n * ```\n */\nexport function contains(needle: string, haystack: string[]): boolean {\n return haystack.some(hay => needle.includes(hay))\n}\n\n/**\n * Returns true if all needles are contained in the haystack.\n * @param needles\n * @param haystack\n * @example\n * ```ts\n * containsAll(['foo', 'bar'], ['foo', 'bar', 'baz']) // true\n * containsAll(['foo', 'bar'], ['foo', 'baz']) // false\n * ```\n */\nexport function containsAll(needles: string[], haystack: string[]): boolean {\n return needles.every(needle => contains(needle, haystack))\n}\n\n/**\n * Returns true if any needle is contained in the haystack.\n * @param needles\n * @param haystack\n * @example\n * ```ts\n * containsAny(['foo', 'bar'], ['foo', 'bar', 'baz']) // true\n * containsAny(['foo', 'bar'], ['foo', 'baz']) // true\n * containsAny(['foo', 'bar'], ['baz']) // false\n * ```\n */\nexport function containsAny(needles: string[], haystack: string[]): boolean {\n return needles.some(needle => contains(needle, haystack))\n}\n\n/**\n * Returns true if none of the needles are contained in the haystack.\n * @param needles\n * @param haystack\n * @example\n * ```ts\n * containsNone(['foo', 'bar'], ['foo', 'bar', 'baz']) // false\n * containsNone(['foo', 'bar'], ['foo', 'baz']) // false\n * containsNone(['foo', 'bar'], ['baz']) // true\n * ```\n */\nexport function containsNone(needles: string[], haystack: string[]): boolean {\n return !containsAny(needles, haystack)\n}\n\n/**\n * Returns true if all needles are contained in the haystack.\n * @param needles\n * @param haystack\n * @example\n * ```ts\n * containsOnly(['foo', 'bar'], ['foo', 'bar', 'baz']) // false\n * containsOnly(['foo', 'bar'], ['foo', 'baz']) // false\n * containsOnly(['foo', 'bar'], ['foo', 'bar']) // true\n * ```\n */\nexport function containsOnly(needles: string[], haystack: string[]): boolean {\n return containsAll(haystack, needles)\n}\n\n/**\n * Returns true if the needle is not contained in the haystack.\n * @param needle\n * @param haystack\n * @example\n * ```ts\n * doesNotContain('foo', ['foo', 'bar']) // false\n * doesNotContain('foo', ['bar']) // true\n * ```\n */\nexport function doesNotContain(needle: string, haystack: string[]): boolean {\n return !contains(needle, haystack)\n}\n",
|
|
6
|
-
"import type { Arrayable, Nullable } from '@stacksjs/types'\nimport { clamp } from '@stacksjs/utils'\n\n/**\n * Convert `Arrayable<T>` to `Array<T>`\n *\n * @category Array\n * @example\n * ```ts\n * toArray('foo') // ['foo']\n * toArray(['foo']) // ['foo']\n * toArray(null) // []\n * toArray(undefined) // []\n * toArray(1) // [1]\n * toArray([1]) // [1]\n * toArray({ foo: 'bar' }) // [{ foo: 'bar' }]\n * toArray([{ foo: 'bar' }]) // [{ foo: 'bar' }]\n * ```\n */\nexport function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {\n array = array ?? []\n return Array.isArray(array) ? array : [array]\n}\n\n/**\n * Flatten `Arrayable<T>` to `Array<T>`\n *\n * @category Array\n * @example\n * ```ts\n * flatten([1, [2, [3, [4, [5]]]]]) // [1, 2, 3, 4, 5]\n * ```\n */\nexport function flatten<T>(array?: Nullable<Arrayable<T | T[]>>): T[] {\n return toArray(array).reduce((acc: T[], val) => acc.concat(Array.isArray(val) ? flatten(val) : (val as T)), [])\n}\n\n/**\n * Use rest arguments to merge arrays\n *\n * @category Array\n * @example\n * ```ts\n * mergeArrayable([1, 2], [3, 4], [5, 6]) // [1, 2, 3, 4, 5, 6]\n * ```\n */\nexport function mergeArrayable<T>(...args: Nullable<Arrayable<T>>[]): Array<T> {\n return args.flatMap(i => toArray(i))\n}\n\nexport type PartitionFilter<T> = (i: T, idx: number, arr: readonly T[]) => any\n\n/**\n * Divide an array into two parts by a filter function\n *\n * @category Array\n * @example\n * ```ts\n * const [odd, even] = partition([1, 2, 3, 4], i => i % 2 != 0)\n * console.log(odd) // [1, 3]\n * console.log(even) // [2, 4]\n * ```\n */\nexport function partition<T>(array: readonly T[], f1: PartitionFilter<T>): [T[], T[]]\nexport function partition<T>(array: readonly T[], f1: PartitionFilter<T>, f2: PartitionFilter<T>): [T[], T[], T[]]\nexport function partition<T>(\n array: readonly T[],\n f1: PartitionFilter<T>,\n f2: PartitionFilter<T>,\n f3: PartitionFilter<T>,\n): [T[], T[], T[], T[]]\nexport function partition<T>(\n array: readonly T[],\n f1: PartitionFilter<T>,\n f2: PartitionFilter<T>,\n f3: PartitionFilter<T>,\n f4: PartitionFilter<T>,\n): [T[], T[], T[], T[], T[]]\nexport function partition<T>(\n array: readonly T[],\n f1: PartitionFilter<T>,\n f2: PartitionFilter<T>,\n f3: PartitionFilter<T>,\n f4: PartitionFilter<T>,\n f5: PartitionFilter<T>,\n): [T[], T[], T[], T[], T[], T[]]\nexport function partition<T>(\n array: readonly T[],\n f1: PartitionFilter<T>,\n f2: PartitionFilter<T>,\n f3: PartitionFilter<T>,\n f4: PartitionFilter<T>,\n f5: PartitionFilter<T>,\n f6: PartitionFilter<T>,\n): [T[], T[], T[], T[], T[], T[], T[]]\nexport function partition<T>(array: readonly T[], ...filters: PartitionFilter<T>[]): any {\n const result: T[][] = Array.from({ length: filters.length + 1 })\n .fill(null)\n .map(() => [])\n\n array.forEach((e, idx, arr) => {\n let i = 0\n for (const filter of filters) {\n if (filter(e, idx, arr)) {\n ;(result[i] as T[]).push(e)\n return\n }\n i += 1\n }\n ;(result[i] as T[]).push(e)\n })\n return result\n}\n\n/**\n * Unique an Array\n *\n * @category Array\n * @example\n * ```ts\n * uniq([1, 2, 3, 3, 2, 1]) // [1, 2, 3]\n * ```\n */\nexport function uniq<T>(array: readonly T[]): T[] {\n return Array.from(new Set(array))\n}\n\n/**\n * Unique an Array\n *\n * @param array\n * @example\n * ```ts\n * unique([1, 2, 3, 3, 2, 1]) // [1, 2, 3]\n * ```\n */\nexport function unique<T>(array: readonly T[]): T[] {\n return uniq(array)\n}\n\n/**\n * Unique an Array by a custom equality function\n *\n * @category Array\n * @example\n * ```ts\n * uniqueBy([1, 2, 3, 3, 2, 1], (a, b) => a === b) // [1, 2, 3]\n * ```\n */\nexport function uniqueBy<T>(array: readonly T[], equalFn: (a: any, b: any) => boolean): T[] {\n return array.reduce((acc: T[], cur: any) => {\n const index = acc.findIndex((item: any) => equalFn(cur, item))\n if (index === -1)\n acc.push(cur)\n return acc\n }, [])\n}\n\n/**\n * Get last item\n *\n * @category Array\n * @example\n * ```ts\n * last([1, 2, 3]) // 3\n * ```\n */\nexport function last(array: readonly []): undefined\nexport function last<T>(array: readonly T[]): T\nexport function last<T>(array: readonly T[]): T | undefined {\n return at(array, -1)\n}\n\n/**\n * Remove an item from Array\n *\n * @category Array\n * @example\n * ```ts\n * const arr = [1, 2, 3]\n * remove(arr, 2) // true\n * Arr.remove(arr, 4) // false\n * console.log(arr) // [1, 3]\n */\nexport function remove<T>(array: T[], value: T): boolean {\n if (!array)\n return false\n\n const index = array.indexOf(value)\n if (index >= 0) {\n array.splice(index, 1)\n return true\n }\n\n return false\n}\n\n/**\n * Get nth item of Array. Negative for backward\n *\n * @category Array\n * @example\n * ```ts\n * at([1, 2, 3], 1) // 2\n * at([1, 2, 3], -1) // 3\n * at([1, 2, 3], 3) // undefined\n * at([1, 2, 3], -4) // undefined\n * ```\n */\nexport function at(array: readonly [], index: number): undefined\nexport function at<T>(array: readonly T[], index: number): T\nexport function at<T>(array: readonly T[] | [], index: number): T | undefined {\n const len = array.length\n if (!len)\n return undefined\n\n if (index < 0)\n index += len\n\n return array[index]\n}\n\n/**\n * Move an item from one index to another\n * @param array\n * @param from\n * @param to\n *\n * @category Array\n * @example\n * ```ts\n * move([1, 2, 3, 4], 0, 2) // [2, 3, 1, 4]\n * move([1, 2, 3, 4], 0, -1) // [2, 3, 4, 1]\n * move([1, 2, 3, 4], -1, 0) // [4, 1, 2, 3]\n * move([1, 2, 3, 4], -1, -2) // [1, 4, 2, 3]\n * move([1, 2, 3, 4], 1, 1) // [1, 2, 3, 4]\n * ```\n */\nexport function move<T>(array: T[], from: number, to: number): T[] {\n const len = array.length\n if (!len)\n return []\n\n if (from < 0)\n from += len\n\n if (to < 0)\n to += len\n\n const item = array.splice(from, 1)[0]\n array.splice(to, 0, item as T)\n return array\n}\n\n/**\n * Clamp a number to the index range of an array.\n *\n * @category Array\n * @example\n * ```ts\n * clampArrayRange([1, 2, 3], 0) // 0\n * clampArrayRange([1, 2, 3], 1) // 1\n * clampArrayRange([1, 2, 3], 2) // 2\n * clampArrayRange([1, 2, 3], 3) // 2\n * clampArrayRange([1, 2, 3], 4) // 2\n * clampArrayRange([1, 2, 3], -1) // 0\n */\nexport function clampArrayRange(arr: readonly unknown[], n: number): number {\n return clamp(n, 0, arr.length - 1)\n}\n\n/**\n * Get random items from an array\n *\n * @category Array\n * @example\n * ```ts\n * sample([1, 2, 3, 4], 2) // [2, 3]\n * ```\n */\nexport function sample<T>(arr: T[], count: number): T[] {\n return Array.from({ length: count }, () => arr[Math.floor(Math.random() * arr.length)]!)\n}\n\n/**\n * Shuffle an array. This function mutates the array.\n *\n * @category Array\n * @example\n * ```ts\n * shuffle([1, 2, 3, 4]) // [2, 4, 1, 3]\n * ```\n */\nexport function shuffle<T>(array: T[]): T[] {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1))\n ;[array[i] as T, array[j] as T] = [array[j] as T, array[i] as T]\n }\n return array\n}\n",
|
|
7
|
-
"/**\n * Returns the average of an array of numbers\n * @param arr\n * @category Array\n * @example\n * ```ts\n * average([1, 2, 3, 4]) // 2.5\n * ```\n */\nexport function average(arr: number[]): number {\n return sum(arr) / arr.length\n}\n\n/**\n * Returns the average of an array of numbers\n * @param arr\n * @category Array\n * @example\n * ```ts\n * avg([1, 2, 3, 4]) // 2.5\n * ```\n */\nexport function avg(arr: number[]): number {\n return average(arr)\n}\n\n/**\n * Returns the median of an array of numbers\n * @param arr\n * @category Array\n * @example\n * ```ts\n * median([1, 2, 3, 4]) // 2.5\n * ```\n */\nexport function median(arr: number[]): number {\n if (arr.length === 0)\n throw new Error('Cannot compute median of an empty array')\n\n const sorted = [...arr].sort((a, b) => a - b)\n\n const mid = Math.floor(sorted.length / 2)\n\n let medianValue: number\n\n if (sorted.length % 2 !== 0)\n medianValue = sorted[mid] as number\n else medianValue = ((sorted[mid] as number) + (sorted[mid - 1] as number)) / 2 // or (sorted[mid - 1] + sorted[mid]) / 2\n\n return medianValue\n}\n\n/**\n * Returns the mode of an array of numbers\n * @param arr\n * @category Array\n * @example\n * ```ts\n * mode([1, 2, 3, 4]) // 1\n * mode([1, 2, 2, 3, 4]) // 2\n * mode([1, 2, 2, 3, 3, 4]) // 2\n * mode([1, 2, 2, 3, 3, 4, 4]) // 2\n * mode([1, 2, 2, 3, 3, 4, 4, 4]) // 4\n * ```\n */\nexport function mode(arr: number[]): number {\n return arr.sort((a, b) => arr.filter(v => v === a).length - arr.filter(v => v === b).length).pop() as number\n}\n\n/**\n * Returns the sum of an array of numbers\n * @param array\n * @category Array\n * @example\n * ```ts\n * sum([1, 2, 3, 4]) // 10\n * ```\n */\nexport function sum(array: readonly number[]): number {\n return array.reduce((acc, cur) => acc + cur, 0)\n}\n\n/**\n * Returns the product of an array of numbers\n * @param array\n * @category Array\n * @example\n * ```ts\n * product([1, 2, 3, 4]) // 24\n * ```\n */\nexport function product(array: readonly number[]): number {\n return array.reduce((acc, cur) => acc * cur, 1)\n}\n\n/**\n * Returns the minimum value of an array of numbers\n * @param array\n * @category Array\n * @example\n * ```ts\n * min([1, 2, 3, 4]) // 1\n * min([1, 2, 3, 4, -1]) // -1\n * ```\n */\nexport function min(array: readonly number[]): number {\n return Math.min(...array)\n}\n\n/**\n * Returns the maximum value of an array of numbers\n * @param array\n * @category Array\n * @example\n * ```ts\n * max([1, 2, 3, 4]) // 4\n * max([1, 2, 3, 4, -1]) // 4\n * ```\n */\nexport function max(array: readonly number[]): number {\n return Math.max(...array)\n}\n\n/**\n * Returns the range of an array of numbers\n * @param array\n * @category Array\n * @example\n * ```ts\n * range([1, 2, 3, 4]) // 3\n * range([1, 2, 3, 4, -1]) // 5\n * range([1, 2, 3, 4, -1, 10]) // 11\n * ```\n */\nexport function range(array: readonly number[]): number {\n return max(array) - min(array)\n}\n\n/**\n * Returns the variance of an array of numbers\n * @param array\n * @category Array\n * @example\n * ```ts\n * variance([1, 2, 3, 4]) // 1.25\n * ```\n * @see https://en.wikipedia.org/wiki/Variance\n */\nexport function variance(array: number[]): number {\n const mean = average(array)\n return average(array.map(num => (num - mean) ** 2))\n}\n\n/**\n * Returns the standard deviation of an array of numbers\n * @param array\n * @category Array\n * @example\n * ```ts\n * standardDeviation([1, 2, 3, 4]) // 1.118033988749895\n * ```\n * @see https://en.wikipedia.org/wiki/Standard_deviation\n * @see https://stackoverflow.com/questions/7343890/standard-deviation-javascript\n */\nexport function standardDeviation(array: number[]): number {\n return Math.sqrt(variance(array))\n}\n\n/**\n * Returns the z-score of a number in an array of numbers\n * @param array\n * @param num\n * @category Array\n * @example\n * ```ts\n * zScore([1, 2, 3, 4], 2) // 0\n * zScore([1, 2, 3, 4], 3) // 0.7071067811865475\n * ```\n * @see https://en.wikipedia.org/wiki/Standard_score\n */\nexport function zScore(array: number[], num: number): number {\n return (num - average(array)) / standardDeviation(array)\n}\n\n/**\n * Returns the percentile of a number in an array of numbers\n * @param array\n * @param num\n * @category Array\n * @example\n * ```ts\n * percentile([1, 2, 3, 4], 2) // 0.25\n * percentile([1, 2, 3, 4], 3) // 0.75\n * ```\n * @see https://en.wikipedia.org/wiki/Percentile\n */\nexport function percentile(array: number[], num: number): number {\n const sorted = [...array].sort((a, b) => a - b)\n const index = (num / 100) * (sorted.length - 1)\n const lower = Math.floor(index)\n const upper = Math.ceil(index)\n const weight = index - lower\n\n if (upper === lower)\n return sorted[index] ?? 0\n return (1 - weight) * (sorted[lower] ?? 0) + weight * (sorted[upper] ?? 0)\n}\n\n/**\n * Returns the interquartile range of an array of numbers\n * @param array\n * @category Array\n * @example\n * ```ts\n * interquartileRange([1, 2, 3, 4]) // 1.5\n * ```\n * @see https://en.wikipedia.org/wiki/Interquartile_range\n * @see https://stackoverflow.com/questions/48719873/how-to-calculate-interquartile-range-in-javascript\n */\nexport function interquartileRange(array: number[]): number {\n const q1 = median(array.slice(0, Math.floor(array.length / 2)))\n const q3 = median(array.slice(Math.ceil(array.length / 2)))\n return q3 - q1\n}\n\n/**\n * Returns the covariance of two arrays of numbers\n * @param array1\n * @param array2\n * @category Array\n * @example\n * ```ts\n * covariance([1, 2, 3, 4], [1, 2, 3, 4]) // 1.25\n * covariance([1, 2, 3, 4], [4, 3, 2, 1]) // -1.25\n * ```\n */\nexport function covariance(array1: number[], array2: number[]): number {\n if (array1.length !== array2.length)\n throw new Error('Arrays must have the same length')\n\n const mean1 = average(array1)\n const mean2 = average(array2)\n\n return average(array1.map((num1, i) => (num1 - mean1) * ((array2[i] as number) - mean2)))\n}\n",
|
|
8
|
-
"import type { Arrayable, Nullable } from '@stacksjs/types'\nimport type { PartitionFilter } from './helpers'\nimport { contains, containsAll, containsAny, containsNone, containsOnly, doesNotContain } from './contains'\nimport {\n at,\n clampArrayRange,\n flatten,\n last,\n mergeArrayable,\n move,\n partition,\n remove,\n sample,\n shuffle,\n toArray,\n uniq,\n uniqueBy,\n} from './helpers'\nimport { average, median, mode, range, sum } from './math'\n\nexport const Arr = {\n contains(needle: string, haystack: string[]): boolean {\n return contains(needle, haystack)\n },\n\n containsAll(needles: string[], haystack: string[]): boolean {\n return containsAll(needles, haystack)\n },\n\n containsAny(needles: string[], haystack: string[]): boolean {\n return containsAny(needles, haystack)\n },\n\n containsNone(needles: string[], haystack: string[]): boolean {\n return containsNone(needles, haystack)\n },\n\n containsOnly(needles: string[], haystack: string[]): boolean {\n return containsOnly(needles, haystack)\n },\n\n doesNotContain(needle: string, haystack: string[]): boolean {\n return doesNotContain(needle, haystack)\n },\n\n toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {\n return toArray(array)\n },\n\n flatten<T>(array?: Nullable<Arrayable<T | T[]>>): T[] {\n return flatten(array)\n },\n\n mergeArrayable<T>(...args: Nullable<Arrayable<T>>[]): Array<T> {\n return mergeArrayable(...args)\n },\n\n partition<T>(array: readonly T[], filter: PartitionFilter<T>): [T[], T[]] {\n return partition(array, filter)\n },\n\n /**\n * Returns a random item/s from the array\n */\n random<T>(arr: T[], count = 1): T[] {\n return sample(arr, count).filter((item): item is T => item != null)\n },\n\n /**\n * Returns random item/s from the array\n */\n sample<T>(arr: T[], count = 1): T[] {\n return sample(arr, count)\n },\n\n unique<T>(arr: T[]): T[] {\n return uniq(arr)\n },\n\n uniqueBy<T>(arr: readonly T[], equalFn: (a: any, b: any) => boolean): T[] {\n return uniqueBy(arr, equalFn)\n },\n\n last<T>(arr: T[]): T | undefined {\n return last(arr)\n },\n\n remove<T>(arr: T[], value: T): boolean {\n return remove(arr, value)\n },\n\n at(arr: any[], index: number): any {\n return at(arr, index)\n },\n\n range(arr: readonly number[]): number {\n return range(arr)\n },\n\n move<T>(arr: T[], from: number, to: number): T[] {\n return move(arr, from, to)\n },\n\n clampArrayRange(arr: readonly unknown[], n: number): number {\n return clampArrayRange(arr, n)\n },\n\n shuffle<T>(arr: T[]): T[] {\n return shuffle(arr)\n },\n\n /**\n * Returns the sum of all items in the array\n */\n sum(arr: number[]): number {\n return sum(arr)\n },\n\n /**\n * Returns the average of all items in the array\n */\n average(arr: number[]): number {\n return average(arr)\n },\n\n avg(arr: number[]): number {\n return average(arr)\n },\n\n /**\n * Returns the median of all items in the array\n */\n median(arr: number[]): number {\n return median(arr)\n },\n\n /**\n * Returns the mode of all items in the array\n */\n mode(arr: number[]): number {\n return mode(arr)\n },\n}\n\nexport const arr: typeof Arr = Arr\n"
|
|
9
|
-
],
|
|
10
|
-
"mappings": "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",
|
|
11
|
-
"debugId": "B6B872CC06F3654D64756E2164756E21",
|
|
12
|
-
"names": []
|
|
13
|
-
}
|
package/src/arr.ts
DELETED
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[]): boolean {
|
|
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[]): boolean {
|
|
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[]): boolean {
|
|
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[]): boolean {
|
|
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[]): boolean {
|
|
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[]): boolean {
|
|
86
|
-
return !contains(needle, haystack)
|
|
87
|
-
}
|
package/src/helpers.ts
DELETED
|
@@ -1,300 +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 | T[]>>): T[] {
|
|
35
|
-
return toArray(array).reduce((acc: T[], val) => acc.concat(Array.isArray(val) ? flatten(val) : (val as 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)
|
|
154
|
-
acc.push(cur)
|
|
155
|
-
return acc
|
|
156
|
-
}, [])
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Get last item
|
|
161
|
-
*
|
|
162
|
-
* @category Array
|
|
163
|
-
* @example
|
|
164
|
-
* ```ts
|
|
165
|
-
* last([1, 2, 3]) // 3
|
|
166
|
-
* ```
|
|
167
|
-
*/
|
|
168
|
-
export function last(array: readonly []): undefined
|
|
169
|
-
export function last<T>(array: readonly T[]): T
|
|
170
|
-
export function last<T>(array: readonly T[]): T | undefined {
|
|
171
|
-
return at(array, -1)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Remove an item from Array
|
|
176
|
-
*
|
|
177
|
-
* @category Array
|
|
178
|
-
* @example
|
|
179
|
-
* ```ts
|
|
180
|
-
* const arr = [1, 2, 3]
|
|
181
|
-
* remove(arr, 2) // true
|
|
182
|
-
* Arr.remove(arr, 4) // false
|
|
183
|
-
* console.log(arr) // [1, 3]
|
|
184
|
-
*/
|
|
185
|
-
export function remove<T>(array: T[], value: T): boolean {
|
|
186
|
-
if (!array)
|
|
187
|
-
return false
|
|
188
|
-
|
|
189
|
-
const index = array.indexOf(value)
|
|
190
|
-
if (index >= 0) {
|
|
191
|
-
array.splice(index, 1)
|
|
192
|
-
return true
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return false
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Get nth item of Array. Negative for backward
|
|
200
|
-
*
|
|
201
|
-
* @category Array
|
|
202
|
-
* @example
|
|
203
|
-
* ```ts
|
|
204
|
-
* at([1, 2, 3], 1) // 2
|
|
205
|
-
* at([1, 2, 3], -1) // 3
|
|
206
|
-
* at([1, 2, 3], 3) // undefined
|
|
207
|
-
* at([1, 2, 3], -4) // undefined
|
|
208
|
-
* ```
|
|
209
|
-
*/
|
|
210
|
-
export function at(array: readonly [], index: number): undefined
|
|
211
|
-
export function at<T>(array: readonly T[], index: number): T
|
|
212
|
-
export function at<T>(array: readonly T[] | [], index: number): T | undefined {
|
|
213
|
-
const len = array.length
|
|
214
|
-
if (!len)
|
|
215
|
-
return undefined
|
|
216
|
-
|
|
217
|
-
if (index < 0)
|
|
218
|
-
index += len
|
|
219
|
-
|
|
220
|
-
return array[index]
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Move an item from one index to another
|
|
225
|
-
* @param array
|
|
226
|
-
* @param from
|
|
227
|
-
* @param to
|
|
228
|
-
*
|
|
229
|
-
* @category Array
|
|
230
|
-
* @example
|
|
231
|
-
* ```ts
|
|
232
|
-
* move([1, 2, 3, 4], 0, 2) // [2, 3, 1, 4]
|
|
233
|
-
* move([1, 2, 3, 4], 0, -1) // [2, 3, 4, 1]
|
|
234
|
-
* move([1, 2, 3, 4], -1, 0) // [4, 1, 2, 3]
|
|
235
|
-
* move([1, 2, 3, 4], -1, -2) // [1, 4, 2, 3]
|
|
236
|
-
* move([1, 2, 3, 4], 1, 1) // [1, 2, 3, 4]
|
|
237
|
-
* ```
|
|
238
|
-
*/
|
|
239
|
-
export function move<T>(array: T[], from: number, to: number): T[] {
|
|
240
|
-
const len = array.length
|
|
241
|
-
if (!len)
|
|
242
|
-
return []
|
|
243
|
-
|
|
244
|
-
if (from < 0)
|
|
245
|
-
from += len
|
|
246
|
-
|
|
247
|
-
if (to < 0)
|
|
248
|
-
to += len
|
|
249
|
-
|
|
250
|
-
const item = array.splice(from, 1)[0]
|
|
251
|
-
array.splice(to, 0, item as T)
|
|
252
|
-
return array
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Clamp a number to the index range of an array.
|
|
257
|
-
*
|
|
258
|
-
* @category Array
|
|
259
|
-
* @example
|
|
260
|
-
* ```ts
|
|
261
|
-
* clampArrayRange([1, 2, 3], 0) // 0
|
|
262
|
-
* clampArrayRange([1, 2, 3], 1) // 1
|
|
263
|
-
* clampArrayRange([1, 2, 3], 2) // 2
|
|
264
|
-
* clampArrayRange([1, 2, 3], 3) // 2
|
|
265
|
-
* clampArrayRange([1, 2, 3], 4) // 2
|
|
266
|
-
* clampArrayRange([1, 2, 3], -1) // 0
|
|
267
|
-
*/
|
|
268
|
-
export function clampArrayRange(arr: readonly unknown[], n: number): number {
|
|
269
|
-
return clamp(n, 0, arr.length - 1)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Get random items from an array
|
|
274
|
-
*
|
|
275
|
-
* @category Array
|
|
276
|
-
* @example
|
|
277
|
-
* ```ts
|
|
278
|
-
* sample([1, 2, 3, 4], 2) // [2, 3]
|
|
279
|
-
* ```
|
|
280
|
-
*/
|
|
281
|
-
export function sample<T>(arr: T[], count: number): T[] {
|
|
282
|
-
return Array.from({ length: count }, () => arr[Math.floor(Math.random() * arr.length)]!)
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Shuffle an array. This function mutates the array.
|
|
287
|
-
*
|
|
288
|
-
* @category Array
|
|
289
|
-
* @example
|
|
290
|
-
* ```ts
|
|
291
|
-
* shuffle([1, 2, 3, 4]) // [2, 4, 1, 3]
|
|
292
|
-
* ```
|
|
293
|
-
*/
|
|
294
|
-
export function shuffle<T>(array: T[]): T[] {
|
|
295
|
-
for (let i = array.length - 1; i > 0; i--) {
|
|
296
|
-
const j = Math.floor(Math.random() * (i + 1))
|
|
297
|
-
;[array[i] as T, array[j] as T] = [array[j] as T, array[i] as T]
|
|
298
|
-
}
|
|
299
|
-
return array
|
|
300
|
-
}
|
package/src/index.ts
DELETED
package/src/macro.ts
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import type { Arrayable, Nullable } from '@stacksjs/types'
|
|
2
|
-
import type { PartitionFilter } from './helpers'
|
|
3
|
-
import { contains, containsAll, containsAny, containsNone, containsOnly, doesNotContain } from './contains'
|
|
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[]): boolean {
|
|
23
|
-
return contains(needle, haystack)
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
containsAll(needles: string[], haystack: string[]): boolean {
|
|
27
|
-
return containsAll(needles, haystack)
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
containsAny(needles: string[], haystack: string[]): boolean {
|
|
31
|
-
return containsAny(needles, haystack)
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
containsNone(needles: string[], haystack: string[]): boolean {
|
|
35
|
-
return containsNone(needles, haystack)
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
containsOnly(needles: string[], haystack: string[]): boolean {
|
|
39
|
-
return containsOnly(needles, haystack)
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
doesNotContain(needle: string, haystack: string[]): boolean {
|
|
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 | T[]>>): 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
|
-
return sample(arr, count)
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
unique<T>(arr: T[]): T[] {
|
|
77
|
-
return uniq(arr)
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
uniqueBy<T>(arr: readonly T[], equalFn: (a: any, b: any) => boolean): T[] {
|
|
81
|
-
return uniqueBy(arr, equalFn)
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
last<T>(arr: T[]): T | undefined {
|
|
85
|
-
return last(arr)
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
remove<T>(arr: T[], value: T): boolean {
|
|
89
|
-
return remove(arr, value)
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
at(arr: any[], index: number): any {
|
|
93
|
-
return at(arr, index)
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
range(arr: readonly number[]): number {
|
|
97
|
-
return range(arr)
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
move<T>(arr: T[], from: number, to: number): T[] {
|
|
101
|
-
return move(arr, from, to)
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
clampArrayRange(arr: readonly unknown[], n: number): number {
|
|
105
|
-
return clampArrayRange(arr, n)
|
|
106
|
-
},
|
|
107
|
-
|
|
108
|
-
shuffle<T>(arr: T[]): T[] {
|
|
109
|
-
return shuffle(arr)
|
|
110
|
-
},
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Returns the sum of all items in the array
|
|
114
|
-
*/
|
|
115
|
-
sum(arr: number[]): number {
|
|
116
|
-
return sum(arr)
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Returns the average of all items in the array
|
|
121
|
-
*/
|
|
122
|
-
average(arr: number[]): number {
|
|
123
|
-
return average(arr)
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
avg(arr: number[]): number {
|
|
127
|
-
return average(arr)
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Returns the median of all items in the array
|
|
132
|
-
*/
|
|
133
|
-
median(arr: number[]): number {
|
|
134
|
-
return median(arr)
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Returns the mode of all items in the array
|
|
139
|
-
*/
|
|
140
|
-
mode(arr: number[]): number {
|
|
141
|
-
return mode(arr)
|
|
142
|
-
},
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export const arr: typeof Arr = Arr
|
package/src/math.ts
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns the average of an array of numbers
|
|
3
|
-
* @param arr
|
|
4
|
-
* @category Array
|
|
5
|
-
* @example
|
|
6
|
-
* ```ts
|
|
7
|
-
* average([1, 2, 3, 4]) // 2.5
|
|
8
|
-
* ```
|
|
9
|
-
*/
|
|
10
|
-
export function average(arr: number[]): number {
|
|
11
|
-
return sum(arr) / arr.length
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Returns the average of an array of numbers
|
|
16
|
-
* @param arr
|
|
17
|
-
* @category Array
|
|
18
|
-
* @example
|
|
19
|
-
* ```ts
|
|
20
|
-
* avg([1, 2, 3, 4]) // 2.5
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export function avg(arr: number[]): number {
|
|
24
|
-
return average(arr)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Returns the median of an array of numbers
|
|
29
|
-
* @param arr
|
|
30
|
-
* @category Array
|
|
31
|
-
* @example
|
|
32
|
-
* ```ts
|
|
33
|
-
* median([1, 2, 3, 4]) // 2.5
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
export function median(arr: number[]): number {
|
|
37
|
-
if (arr.length === 0)
|
|
38
|
-
throw new Error('Cannot compute median of an empty array')
|
|
39
|
-
|
|
40
|
-
const sorted = [...arr].sort((a, b) => a - b)
|
|
41
|
-
|
|
42
|
-
const mid = Math.floor(sorted.length / 2)
|
|
43
|
-
|
|
44
|
-
let medianValue: number
|
|
45
|
-
|
|
46
|
-
if (sorted.length % 2 !== 0)
|
|
47
|
-
medianValue = sorted[mid] as number
|
|
48
|
-
else medianValue = ((sorted[mid] as number) + (sorted[mid - 1] as number)) / 2 // or (sorted[mid - 1] + sorted[mid]) / 2
|
|
49
|
-
|
|
50
|
-
return medianValue
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Returns the mode of an array of numbers
|
|
55
|
-
* @param arr
|
|
56
|
-
* @category Array
|
|
57
|
-
* @example
|
|
58
|
-
* ```ts
|
|
59
|
-
* mode([1, 2, 3, 4]) // 1
|
|
60
|
-
* mode([1, 2, 2, 3, 4]) // 2
|
|
61
|
-
* mode([1, 2, 2, 3, 3, 4]) // 2
|
|
62
|
-
* mode([1, 2, 2, 3, 3, 4, 4]) // 2
|
|
63
|
-
* mode([1, 2, 2, 3, 3, 4, 4, 4]) // 4
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
export function mode(arr: number[]): number {
|
|
67
|
-
return arr.sort((a, b) => arr.filter(v => v === a).length - arr.filter(v => v === b).length).pop() as number
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Returns the sum of an array of numbers
|
|
72
|
-
* @param array
|
|
73
|
-
* @category Array
|
|
74
|
-
* @example
|
|
75
|
-
* ```ts
|
|
76
|
-
* sum([1, 2, 3, 4]) // 10
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
export function sum(array: readonly number[]): number {
|
|
80
|
-
return array.reduce((acc, cur) => acc + cur, 0)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Returns the product of an array of numbers
|
|
85
|
-
* @param array
|
|
86
|
-
* @category Array
|
|
87
|
-
* @example
|
|
88
|
-
* ```ts
|
|
89
|
-
* product([1, 2, 3, 4]) // 24
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
|
-
export function product(array: readonly number[]): number {
|
|
93
|
-
return array.reduce((acc, cur) => acc * cur, 1)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Returns the minimum value of an array of numbers
|
|
98
|
-
* @param array
|
|
99
|
-
* @category Array
|
|
100
|
-
* @example
|
|
101
|
-
* ```ts
|
|
102
|
-
* min([1, 2, 3, 4]) // 1
|
|
103
|
-
* min([1, 2, 3, 4, -1]) // -1
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
|
-
export function min(array: readonly number[]): number {
|
|
107
|
-
return Math.min(...array)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Returns the maximum value of an array of numbers
|
|
112
|
-
* @param array
|
|
113
|
-
* @category Array
|
|
114
|
-
* @example
|
|
115
|
-
* ```ts
|
|
116
|
-
* max([1, 2, 3, 4]) // 4
|
|
117
|
-
* max([1, 2, 3, 4, -1]) // 4
|
|
118
|
-
* ```
|
|
119
|
-
*/
|
|
120
|
-
export function max(array: readonly number[]): number {
|
|
121
|
-
return Math.max(...array)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Returns the range of an array of numbers
|
|
126
|
-
* @param array
|
|
127
|
-
* @category Array
|
|
128
|
-
* @example
|
|
129
|
-
* ```ts
|
|
130
|
-
* range([1, 2, 3, 4]) // 3
|
|
131
|
-
* range([1, 2, 3, 4, -1]) // 5
|
|
132
|
-
* range([1, 2, 3, 4, -1, 10]) // 11
|
|
133
|
-
* ```
|
|
134
|
-
*/
|
|
135
|
-
export function range(array: readonly number[]): number {
|
|
136
|
-
return max(array) - min(array)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Returns the variance of an array of numbers
|
|
141
|
-
* @param array
|
|
142
|
-
* @category Array
|
|
143
|
-
* @example
|
|
144
|
-
* ```ts
|
|
145
|
-
* variance([1, 2, 3, 4]) // 1.25
|
|
146
|
-
* ```
|
|
147
|
-
* @see https://en.wikipedia.org/wiki/Variance
|
|
148
|
-
*/
|
|
149
|
-
export function variance(array: number[]): number {
|
|
150
|
-
const mean = average(array)
|
|
151
|
-
return average(array.map(num => (num - mean) ** 2))
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Returns the standard deviation of an array of numbers
|
|
156
|
-
* @param array
|
|
157
|
-
* @category Array
|
|
158
|
-
* @example
|
|
159
|
-
* ```ts
|
|
160
|
-
* standardDeviation([1, 2, 3, 4]) // 1.118033988749895
|
|
161
|
-
* ```
|
|
162
|
-
* @see https://en.wikipedia.org/wiki/Standard_deviation
|
|
163
|
-
* @see https://stackoverflow.com/questions/7343890/standard-deviation-javascript
|
|
164
|
-
*/
|
|
165
|
-
export function standardDeviation(array: number[]): number {
|
|
166
|
-
return Math.sqrt(variance(array))
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Returns the z-score of a number in an array of numbers
|
|
171
|
-
* @param array
|
|
172
|
-
* @param num
|
|
173
|
-
* @category Array
|
|
174
|
-
* @example
|
|
175
|
-
* ```ts
|
|
176
|
-
* zScore([1, 2, 3, 4], 2) // 0
|
|
177
|
-
* zScore([1, 2, 3, 4], 3) // 0.7071067811865475
|
|
178
|
-
* ```
|
|
179
|
-
* @see https://en.wikipedia.org/wiki/Standard_score
|
|
180
|
-
*/
|
|
181
|
-
export function zScore(array: number[], num: number): number {
|
|
182
|
-
return (num - average(array)) / standardDeviation(array)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Returns the percentile of a number in an array of numbers
|
|
187
|
-
* @param array
|
|
188
|
-
* @param num
|
|
189
|
-
* @category Array
|
|
190
|
-
* @example
|
|
191
|
-
* ```ts
|
|
192
|
-
* percentile([1, 2, 3, 4], 2) // 0.25
|
|
193
|
-
* percentile([1, 2, 3, 4], 3) // 0.75
|
|
194
|
-
* ```
|
|
195
|
-
* @see https://en.wikipedia.org/wiki/Percentile
|
|
196
|
-
*/
|
|
197
|
-
export function percentile(array: number[], num: number): number {
|
|
198
|
-
const sorted = [...array].sort((a, b) => a - b)
|
|
199
|
-
const index = (num / 100) * (sorted.length - 1)
|
|
200
|
-
const lower = Math.floor(index)
|
|
201
|
-
const upper = Math.ceil(index)
|
|
202
|
-
const weight = index - lower
|
|
203
|
-
|
|
204
|
-
if (upper === lower)
|
|
205
|
-
return sorted[index] ?? 0
|
|
206
|
-
return (1 - weight) * (sorted[lower] ?? 0) + weight * (sorted[upper] ?? 0)
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Returns the interquartile range of an array of numbers
|
|
211
|
-
* @param array
|
|
212
|
-
* @category Array
|
|
213
|
-
* @example
|
|
214
|
-
* ```ts
|
|
215
|
-
* interquartileRange([1, 2, 3, 4]) // 1.5
|
|
216
|
-
* ```
|
|
217
|
-
* @see https://en.wikipedia.org/wiki/Interquartile_range
|
|
218
|
-
* @see https://stackoverflow.com/questions/48719873/how-to-calculate-interquartile-range-in-javascript
|
|
219
|
-
*/
|
|
220
|
-
export function interquartileRange(array: number[]): number {
|
|
221
|
-
const q1 = median(array.slice(0, Math.floor(array.length / 2)))
|
|
222
|
-
const q3 = median(array.slice(Math.ceil(array.length / 2)))
|
|
223
|
-
return q3 - q1
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Returns the covariance of two arrays of numbers
|
|
228
|
-
* @param array1
|
|
229
|
-
* @param array2
|
|
230
|
-
* @category Array
|
|
231
|
-
* @example
|
|
232
|
-
* ```ts
|
|
233
|
-
* covariance([1, 2, 3, 4], [1, 2, 3, 4]) // 1.25
|
|
234
|
-
* covariance([1, 2, 3, 4], [4, 3, 2, 1]) // -1.25
|
|
235
|
-
* ```
|
|
236
|
-
*/
|
|
237
|
-
export function covariance(array1: number[], array2: number[]): number {
|
|
238
|
-
if (array1.length !== array2.length)
|
|
239
|
-
throw new Error('Arrays must have the same length')
|
|
240
|
-
|
|
241
|
-
const mean1 = average(array1)
|
|
242
|
-
const mean2 = average(array2)
|
|
243
|
-
|
|
244
|
-
return average(array1.map((num1, i) => (num1 - mean1) * ((array2[i] as number) - mean2)))
|
|
245
|
-
}
|