swisslist
Version:
A functional, immutable list implementation with a rich set of methods for manipulating collections.
1 lines • 7.97 kB
JavaScript
var e=class e{constructor(e){this.internal=e}[Symbol.iterator](){return this.internal[Symbol.iterator]()}static isList(t){return t instanceof e}static empty(){return new e([])}static of(...t){return new e(t)}static from(t){if(t==null)throw TypeError(`List.from: iterable cannot be null or undefined`);return new e(Array.from(t))}static range(t,n,r=1){if(!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(r))throw TypeError(`List.range: all arguments must be finite numbers`);if(r===0)throw RangeError(`List.range: step cannot be zero`);if(r>0&&t>n||r<0&&t<n)return e.empty();let i=[];for(let e=t;r>0?e<=n:e>=n;e+=r)i.push(e);return new e(i)}get size(){return this.internal.length}resolveIndex(e){return e<0?e+this.size:e}isOutOfBounds(e){let t=this.resolveIndex(e);return t<0||t>=this.size}isFirst(e){return!this.isEmpty()&&e===0}isLast(e){return e===this.size-1}append(...t){return new e([...this.internal,...t])}at(e){return this.internal[this.resolveIndex(e)]}chunk(t){let n=e.empty();for(let r=0;r<this.size;r+=t)n=n.append(e.from(this.internal.slice(r,r+t)));return n}clone(t){return t?new e(structuredClone(this.internal)):new e(this.internal.slice())}compact(){return this.filter(e=>e!=null)}compactMap(t){let n=[];for(let e of this.internal){let r=t(e);r!=null&&n.push(r)}return new e(n)}concat(t){return new e([...this.internal,...t.internal])}countBy(e){let t={};for(let n of this.internal){let r=e(n);t[r]=(t[r]||0)+1}return t}difference(t){return new e(this.internal.filter(e=>!t.internal.includes(e)))}differenceBy(t,n){let r=new Set(t.internal.map(n));return new e(this.internal.filter(e=>!r.has(n(e))))}drop(t){let n=Math.max(0,Math.min(t,this.size));return new e(this.internal.slice(n))}dropFirst(){return this.drop(1)}dropLast(t){let n=Math.max(0,Math.min(t,this.size));return new e(this.internal.slice(0,this.size-n))}dropWhile(t){let n=0;for(;n<this.size&&t(this.internal[n]);)n++;return new e(this.internal.slice(n))}each(e){return this.internal.forEach(e),this}enumerate(){return new e(this.internal.map((e,t)=>[t,e]))}every(e){return this.internal.every(e)}filter(t){return new e(this.internal.filter(t))}find(e){return this.internal.find(e)}findIndex(e){let t=this.internal.findIndex(e);return t===-1?void 0:t}findLast(e){return this.internal.findLast(e)}findLastIndex(e){let t=this.internal.findLastIndex(e);return t===-1?void 0:t}first(){return this.internal[0]}flat(t){return new e(this.internal.flat(t))}flatMap(t){return new e(this.internal.flatMap(t))}groupBy(t){let n={};for(let r of this.internal){let i=t(r);n[i]=(n[i]||e.empty()).append(r)}return n}has(e){return this.internal.includes(e)}insertAt(e,...t){return this.splice(e,0,...t)}intersect(t){return new e(this.internal.filter(e=>t.has(e)))}intersectBy(t,n){let r=new Set(t.internal.map(n));return new e(this.internal.filter(e=>r.has(n(e))))}isEmpty(){return this.size===0}last(){return this.internal[this.size-1]}map(t){return new e(this.internal.map(t))}move(t,n){if(this.isOutOfBounds(t)||this.isOutOfBounds(n))return this;let r=this.resolveIndex(t),i=this.resolveIndex(n),a=[...this.internal],[o]=a.splice(r,1);return a.splice(i,0,o),new e(a)}partition(t){let n=[],r=[];for(let e of this.internal)t(e)?n.push(e):r.push(e);return[new e(n),new e(r)]}prepend(...t){return new e([...t,...this.internal])}random(){return this.internal[Math.floor(Math.random()*this.size)]}reduce(e,t){return this.internal.reduce(t,e)}reduceRight(e,t){return this.internal.reduceRight(t,e)}removeAt(e){return this.splice(e,1)}replaceAt(t,n){if(this.isOutOfBounds(t))return this;let r=this.resolveIndex(t),i=[...this.internal];return i[r]=n,new e(i)}reverse(){return new e([...this.internal].reverse())}rotate(t){let n=[...this.internal],r=this.resolveIndex(t);return r===0||(r>0?n.unshift(...n.splice(-r)):n.push(...n.splice(0,-r))),new e(n)}shuffle(t=1){let n=[...this.internal];for(let e=0;e<t;e++)n.sort(()=>Math.random()-.5);return new e(n)}slice(t,n){return new e(this.internal.slice(t,n))}some(e){return this.internal.some(e)}sort(t){return new e([...this.internal].sort(t))}splice(t,n,...r){let i=[...this.internal],a=this.resolveIndex(t),o=Math.max(0,Math.min(a,i.length));return n===void 0?new e(i.slice(0,o)):(i.splice(o,n,...r),new e(i))}swap(t,n){if(this.isOutOfBounds(t)||this.isOutOfBounds(n))return this;let r=this.resolveIndex(t),i=this.resolveIndex(n),a=[...this.internal];return[a[r],a[i]]=[a[i],a[r]],new e(a)}sumBy(e){if(this.isEmpty())return 0;let t=0;for(let n of this.internal){let r=e(n);if(typeof r!=`number`||!Number.isFinite(r))throw TypeError(`sumBy: selector function must return a finite number`);t+=r}return t}averageBy(e){return this.isEmpty()?0:this.sumBy(e)/this.size}medianBy(e){if(this.isEmpty())return 0;if(this.size===1)return e(this.internal[0]);let t=Array.from({length:this.size},(t,n)=>{let r=e(this.internal[n]);if(typeof r!=`number`||!Number.isFinite(r))throw TypeError(`medianBy: selector function must return finite numbers`);return r});t.sort((e,t)=>e-t);let n=Math.floor(t.length/2);return t.length%2==0?(t[n-1]+t[n])/2:t[n]}productBy(e){if(this.isEmpty())return 1;let t=1;for(let n of this.internal){let r=e(n);if(typeof r!=`number`||!Number.isFinite(r))throw TypeError(`productBy: selector function must return a finite number`);t*=r}return t}varianceBy(e){if(this.isEmpty()||this.size===1)return 0;let t=0,n=0,r=0;for(let i of this.internal){let a=e(i);if(typeof a!=`number`||!Number.isFinite(a))throw TypeError(`varianceBy: selector function must return finite numbers`);t+=a,n+=a*a,r++}let i=t/r;return n/r-i*i}standardDeviationBy(e){return Math.sqrt(this.varianceBy(e))}modeBy(e){if(this.isEmpty())return;if(this.size===1)return e(this.internal[0]);let t=new Map,n=0,r;for(let i of this.internal){let a=e(i);if(typeof a!=`number`||!Number.isFinite(a))throw TypeError(`modeBy: selector function must return finite numbers`);let o=(t.get(a)||0)+1;t.set(a,o),o>n&&(n=o,r=a)}return r}rangeBy(e){if(this.isEmpty())return 0;let t=1/0,n=-1/0;for(let r of this.internal){let i=e(r);if(typeof i!=`number`||!Number.isFinite(i))throw TypeError(`rangeBy: selector function must return finite numbers`);t=Math.min(t,i),n=Math.max(n,i)}return n-t}geometricMeanBy(e){if(this.isEmpty())return 0;if(this.size===1)return e(this.internal[0]);let t=1;for(let n of this.internal){let r=e(n);if(typeof r!=`number`||!Number.isFinite(r))throw TypeError(`geometricMeanBy: selector function must return finite numbers`);if(r<0)throw Error(`geometricMeanBy: cannot calculate geometric mean of negative numbers`);t*=r}return t**(1/this.size)}harmonicMeanBy(e){if(this.isEmpty())return 0;if(this.size===1)return e(this.internal[0]);let t=0;for(let n of this.internal){let r=e(n);if(typeof r!=`number`||!Number.isFinite(r))throw TypeError(`harmonicMeanBy: selector function must return finite numbers`);if(r===0)throw Error(`harmonicMeanBy: cannot calculate harmonic mean when any value is 0`);t+=1/r}return this.size/t}take(e){let t=Math.max(0,Math.min(e,this.size));return this.slice(0,t)}takeWhile(t){let n=0;for(;n<this.size&&t(this.internal[n]);)n++;return new e(this.internal.slice(0,n))}toArray(){return Array.from(this.internal)}toJSON(){return this.toArray()}toSet(){return new Set(this)}toString(){return this.internal.toString()}union(e){return this.concat(e).unique()}unique(){return new e([...new Set(this.internal)])}uniqueBy(e){let t=new Set;return this.filter(n=>{let r=e(n);return t.has(r)?!1:(t.add(r),!0)})}updateAt(t,n){if(this.isOutOfBounds(t))return this;let r=this.resolveIndex(t),i=[...this.internal];return i[r]=n,new e(i)}updateWhere(e,t){return this.map((n,r)=>e(n,r)?t(n):n)}zip(t){if(this.isEmpty()||t.isEmpty())return e.empty();let n=[],r=Math.min(this.size,t.size);for(let e=0;e<r;e++)n.push([this.internal[e],t.internal[e]]);return new e(n)}zipWith(t,n){if(this.isEmpty()||t.isEmpty())return e.empty();let r=[],i=Math.min(this.size,t.size);for(let e=0;e<i;e++)r.push(n(this.internal[e],t.internal[e]));return new e(r)}};export{e as List};