@stryke/helpers
Version:
A package containing miscellaneous helper functions that are used across many different Storm Software projects.
2 lines (1 loc) • 2.81 kB
JavaScript
import{removeAccents as b}from"./remove-accents";const I={CASE_SENSITIVE_EQUAL:7,EQUAL:6,STARTS_WITH:5,WORD_STARTS_WITH:4,CONTAINS:3,ACRONYM:2,MATCHES:1,NO_MATCH:0},g=(n,e)=>String(n.rankedValue).localeCompare(String(e.rankedValue));function T(n,e,t={}){const{keys:r,threshold:c=I.MATCHES,baseSort:s=g,sorter:y=i=>i.sort((o,l)=>V(o,l,s))}=t,u=n.reduce((i,o,l)=>a(i,o,l),[]);return y(u).map(({item:i})=>i);function a(i,o,l){const m=O(o,r,e,t),{rank:p,keyThreshold:f=c}=m;return p>=f&&i.push({...m,item:o,index:l}),i}}T.rankings=I;function O(n,e,t,r){if(!e){const s=n;return{rankedValue:s,rank:k(s,t,r),keyIndex:-1,keyThreshold:r.threshold}}return M(n,e).reduce(({rank:s,rankedValue:y,keyIndex:u,keyThreshold:a},{itemValue:i,attributes:o},l)=>{let m=k(i,t,r),p=y;const{minRanking:f,maxRanking:d,threshold:R}=o;return m<f&&m>=I.MATCHES?m=f:m>d&&(m=d),m>s&&(s=m,u=l,a=R,p=i),{rankedValue:p,rank:s,keyIndex:u,keyThreshold:a}},{rankedValue:n,rank:I.NO_MATCH,keyIndex:-1,keyThreshold:r.threshold})}function k(n,e,t){return n=A(n,t),e=A(e,t),e.length>n.length?I.NO_MATCH:n===e?I.CASE_SENSITIVE_EQUAL:(n=n.toLowerCase(),e=e.toLowerCase(),n===e?I.EQUAL:n.startsWith(e)?I.STARTS_WITH:n.includes(` ${e}`)?I.WORD_STARTS_WITH:n.includes(e)?I.CONTAINS:e.length===1?I.NO_MATCH:S(n).includes(e)?I.ACRONYM:C(n,e))}function S(n){let e="";const t=n.split(" ");for(const r of t){const c=r.split("-");for(const s of c)e+=s.slice(0,1)}return e}function C(n,e){let t=0,r=0;function c(a,i,o){for(let l=o,m=i.length;l<m;l++)if(i[l]===a)return t+=1,l+1;return-1}function s(a){const i=1/a,o=t/e.length;return I.MATCHES+o*i}const y=c(e[0],n,0);if(y<0)return I.NO_MATCH;r=y;for(let a=1,i=e.length;a<i;a++){const o=e[a];if(r=c(o,n,r),!(r>-1))return I.NO_MATCH}const u=r-y;return s(u)}function V(n,e,t){const{rank:s,keyIndex:y}=n,{rank:u,keyIndex:a}=e;return s===u?y===a?t(n,e):y<a?-1:1:s>u?-1:1}function A(n,{keepDiacritics:e}){return n=`${n}`,e||(n=b(n)),n}function K(n,e){typeof e=="object"&&(e=e.key);let t;if(typeof e=="function")t=e(n);else if(n===null)t=null;else if(Object.hasOwnProperty.call(n,e))t=n[e];else{if(e.includes("."))return x(e,n);t=null}return t===null?[]:Array.isArray(t)?t:[String(t)]}function x(n,e){const t=n.split(".");let r=[e];for(let c=0,s=t.length;c<s;c++){const y=t[c];let u=[];for(let a=0,i=r.length;a<i;a++){const o=r[a];if(o!==null)if(y&&Object.hasOwnProperty.call(o,y)){const l=o[y];l!==null&&u.push(l)}else o&&y==="*"&&(u=[...u,o])}r=u}return Array.isArray(r[0])?[].concat(...r):r}function M(n,e){const t=[];for(let r=0,c=e.length;r<c;r++){const s=e[r],y=H(s),u=K(n,s);for(let a=0,i=u.length;a<i;a++)t.push({itemValue:u[a],attributes:y})}return t}const h={maxRanking:1/0,minRanking:-1/0};function H(n){return typeof n=="string"?h:{...h,...n}}export{g as defaultBaseSortFn,T as matchSorter,I as rankings};