-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.min.js
1 lines (1 loc) · 4.25 KB
/
utils.min.js
1
const memoize=f=>{var cache={};return function(...args){return cache[args]??(cache[args]=f.apply(this,args))}};const floatEquals=(a,b,p=Number.EPSILON)=>Math.abs(a-b)<p;const clamp=(a,min=0,max=1)=>a<min?min:a>max?max:a;const frac=a=>a>=0?a-Math.floor(a):a-Math.ceil(a);const round=(n,d=0)=>{const p=Math.pow(10,d);return Math.round(n*p+Number.EPSILON)/p};const lerp=(a,b,i)=>a+(b-a)*i;const unlerp=(a,b,i)=>(i-a)/(b-a);const blerp=(c00,c10,c01,c11,ix,iy)=>lerp(lerp(c00,c10,ix),lerp(c01,c11,ix),iy);const remap=(i,a1,a2,b1,b2)=>b1+(i-a1)*(b2-b1)/(a2-a1);const smoothstep=(a,b,i)=>lerp(a,b,3*Math.pow(i,2)-2*Math.pow(i,3));const radians=degrees=>Math.PI/180*degrees;const degrees=radians=>180/Math.PI*radians;const randomBetween=(min,max)=>Math.random()*(max-min)+min;const randomIntBetween=(min,max)=>Math.floor(Math.random()*(max-min+1))+min;const cltRandom=(mu=.5,sigma=.5,samples=2)=>{let total=0;for(let i=samples;i--;){total+=Math.random()}return mu+(total-samples/2)/(samples/2)*sigma};const cltRandomInt=(min,max)=>Math.floor(min+cltRandom(.5,.5,2)*(max+1-min));const weightedRandom=w=>{let total=w.reduce((a,i)=>a+i,0),n=0;const r=Math.random()*total;while(total>r){total-=w[n++]}return n-1};const lerpArray=(a,i,f=lerp)=>{const s=i*(a.length-1);const p=clamp(Math.trunc(s),0,a.length-1);return f(a[p]||0,a[p+1]||0,frac(s))};const dot=(a,b)=>a.reduce((n,v,i)=>n+v*b[i],0);const factorial=a=>{let result=1;for(let i=2;i<=a;i++){result*=i}return result};const npr=(n,r)=>factorial(n)/factorial(n-r);const ncr=(n,r)=>factorial(n)/(factorial(r)*factorial(n-r));const permutations=(a,r)=>{if(r===1){return a.map(item=>[item])}return a.reduce((acc,item,i)=>[...acc,...permutations(a.slice(0,i).concat(a.slice(i+1)),r-1).map(c=>[item,...c])],[])};const combinations=(a,r)=>{if(r===1){return a.map(item=>[item])}return a.reduce((acc,item,i)=>[...acc,...combinations(a.slice(i+1),r-1).map(c=>[item,...c])],[])};const cartesian=(...arr)=>arr.reduce((a,b)=>a.flatMap(c=>b.map(d=>[...c,d])),[[]]);const times=(f,n)=>Array(n).fill(0).map((_,i)=>f(i));const range=n=>times(i=>i,n);const zip=(...a)=>times(i=>a.map(a=>a[i]),Math.max(...a.map(a=>a.length)));const at=(a,i)=>a[i<0?a.length-Math.abs(i+1)%a.length-1:i%a.length];const peek=a=>{if(!a.length){return undefined}return a[a.length-1]};const ind=(x,y,w)=>x+y*w;const pos=(i,w)=>[i%w,Math.floor(i/w)];const chunk=(a,n)=>times(i=>a.slice(i*n,i*n+n),Math.ceil(a.length/n));const shuffle=a=>a.slice().sort(()=>Math.random()-.5);const flat=(o,concatenator=".")=>{return Object.keys(o).reduce((acc,key)=>{if(o[key]instanceof Date){return{...acc,[key]:o[key].toISOString()}}if(typeof o[key]!=="object"||!o[key]){return{...acc,[key]:o[key]}}const flattened=flat(o[key],concatenator);return{...acc,...Object.keys(flattened).reduce((childAcc,childKey)=>({...childAcc,[`${key}${concatenator}${childKey}`]:flattened[childKey]}),{})}},{})};const unflat=(o,concatenator=".")=>{let result={},temp,substrings,property,i;for(property in o){substrings=property.split(concatenator);temp=result;for(i=0;i<substrings.length-1;i++){if(!(substrings[i]in temp)){if(isFinite(substrings[i+1])){temp[substrings[i]]=[]}else{temp[substrings[i]]={}}}temp=temp[substrings[i]]}temp[substrings[substrings.length-1]]=o[property]}return result};const split=(array,predicate)=>{const result=[];let current=[];for(const value of array){if(predicate(value)){if(current.length){result.push(current)}current=[value]}else{current.push(value)}}result.push(current);return result};const pluck=(o,...keys)=>{return keys.reduce((result,key)=>Object.assign(result,{[key]:o[key]}),{})};const exclude=(o,...keys)=>{return Object.fromEntries(Object.entries(o).filter(([key])=>!keys.includes(key)))};if(typeof module!=="undefined"){module.exports={memoize:memoize,floatEquals:floatEquals,clamp:clamp,frac:frac,round:round,lerp:lerp,unlerp:unlerp,blerp:blerp,remap:remap,smoothstep:smoothstep,radians:radians,degrees:degrees,randomBetween:randomBetween,randomIntBetween:randomIntBetween,cltRandom:cltRandom,cltRandomInt:cltRandomInt,weightedRandom:weightedRandom,lerpArray:lerpArray,dot:dot,factorial:factorial,npr:npr,ncr:ncr,permutations:permutations,combinations:combinations,cartesian:cartesian,times:times,range:range,zip:zip,at:at,peek:peek,ind:ind,pos:pos,chunk:chunk,shuffle:shuffle,flat:flat,unflat:unflat,split:split,pluck:pluck,exclude:exclude}}