es-sifter
Version:
A library for textually searching arrays and hashes of objects by property (or multiple properties). Designed specifically for autocomplete.
2 lines • 7.5 kB
JavaScript
/*! sifter.js | https://github.com/brianreavis/sifter.js | Apache License (v2) */
"use strict";var DIACRITICS={a:"[a\u1e00\u1e01\u0102\u0103\xc2\xe2\u01cd\u01ce\u023a\u2c65\u0226\u0227\u1ea0\u1ea1\xc4\xe4\xc0\xe0\xc1\xe1\u0100\u0101\xc3\xe3\xc5\xe5\u0105\u0104\xc3\u0105\u0104]",b:"[b\u2422\u03b2\u0392B\u0e3f\ud800\udf01\u16d2]",c:"[c\u0106\u0107\u0108\u0109\u010c\u010d\u010a\u010bC\u0304c\u0304\xc7\xe7\u1e08\u1e09\u023b\u023c\u0187\u0188\u0255\u1d04\uff23\uff43]",d:"[d\u010e\u010f\u1e0a\u1e0b\u1e10\u1e11\u1e0c\u1e0d\u1e12\u1e13\u1e0e\u1e0f\u0110\u0111D\u0326d\u0326\u0189\u0256\u018a\u0257\u018b\u018c\u1d6d\u1d81\u1d91\u0221\u1d05\uff24\uff44\xf0]",e:"[e\xc9\xe9\xc8\xe8\xca\xea\u1e18\u1e19\u011a\u011b\u0114\u0115\u1ebc\u1ebd\u1e1a\u1e1b\u1eba\u1ebb\u0116\u0117\xcb\xeb\u0112\u0113\u0228\u0229\u0118\u0119\u1d92\u0246\u0247\u0204\u0205\u1ebe\u1ebf\u1ec0\u1ec1\u1ec4\u1ec5\u1ec2\u1ec3\u1e1c\u1e1d\u1e16\u1e17\u1e14\u1e15\u0206\u0207\u1eb8\u1eb9\u1ec6\u1ec7\u2c78\u1d07\uff25\uff45\u0258\u01dd\u018f\u0190\u03b5]",f:"[f\u0191\u0192\u1e1e\u1e1f]",g:"[g\u0262\u20b2\u01e4\u01e5\u011c\u011d\u011e\u011f\u0122\u0123\u0193\u0260\u0120\u0121]",h:"[h\u0124\u0125\u0126\u0127\u1e28\u1e29\u1e96\u1e96\u1e24\u1e25\u1e22\u1e23\u0266\u02b0\u01f6\u0195]",i:"[i\xcd\xed\xcc\xec\u012c\u012d\xce\xee\u01cf\u01d0\xcf\xef\u1e2e\u1e2f\u0128\u0129\u012e\u012f\u012a\u012b\u1ec8\u1ec9\u0208\u0209\u020a\u020b\u1eca\u1ecb\u1e2c\u1e2d\u0197\u0268\u0268\u0306\u1d7b\u1d96\u0130iI\u0131\u026a\uff29\uff49]",j:"[j\u0237\u0134\u0135\u0248\u0249\u029d\u025f\u02b2]",k:"[k\u0198\u0199\ua740\ua741\u1e30\u1e31\u01e8\u01e9\u1e32\u1e33\u1e34\u1e35\u03ba\u03f0\u20ad]",l:"[l\u0141\u0142\u013d\u013e\u013b\u013c\u0139\u013a\u1e36\u1e37\u1e38\u1e39\u1e3c\u1e3d\u1e3a\u1e3b\u013f\u0140\u023d\u019a\u2c60\u2c61\u2c62\u026b\u026c\u1d85\u026d\u0234\u029f\uff2c\uff4c]",n:"[n\u0143\u0144\u01f8\u01f9\u0147\u0148\xd1\xf1\u1e44\u1e45\u0145\u0146\u1e46\u1e47\u1e4a\u1e4b\u1e48\u1e49N\u0308n\u0308\u019d\u0272\u0220\u019e\u1d70\u1d87\u0273\u0235\u0274\uff2e\uff4e\u014a\u014b]",o:"[o\xd8\xf8\xd6\xf6\xd3\xf3\xd2\xf2\xd4\xf4\u01d1\u01d2\u0150\u0151\u014e\u014f\u022e\u022f\u1ecc\u1ecd\u019f\u0275\u01a0\u01a1\u1ece\u1ecf\u014c\u014d\xd5\xf5\u01ea\u01eb\u020c\u020d\u0555\u0585]",p:"[p\u1e54\u1e55\u1e56\u1e57\u2c63\u1d7d\u01a4\u01a5\u1d71]",q:"[q\ua756\ua757\u02a0\u024a\u024b\ua758\ua759q\u0303]",r:"[r\u0154\u0155\u024c\u024d\u0158\u0159\u0156\u0157\u1e58\u1e59\u0210\u0211\u0212\u0213\u1e5a\u1e5b\u2c64\u027d]",s:"[s\u015a\u015b\u1e60\u1e61\u1e62\u1e63\ua7a8\ua7a9\u015c\u015d\u0160\u0161\u015e\u015f\u0218\u0219S\u0308s\u0308]",t:"[t\u0164\u0165\u1e6a\u1e6b\u0162\u0163\u1e6c\u1e6d\u01ae\u0288\u021a\u021b\u1e70\u1e71\u1e6e\u1e6f\u01ac\u01ad]",u:"[u\u016c\u016d\u0244\u0289\u1ee4\u1ee5\xdc\xfc\xda\xfa\xd9\xf9\xdb\xfb\u01d3\u01d4\u0170\u0171\u016c\u016d\u01af\u01b0\u1ee6\u1ee7\u016a\u016b\u0168\u0169\u0172\u0173\u0214\u0215\u222a]",v:"[v\u1e7c\u1e7d\u1e7e\u1e7f\u01b2\u028b\ua75e\ua75f\u2c71\u028b]",w:"[w\u1e82\u1e83\u1e80\u1e81\u0174\u0175\u1e84\u1e85\u1e86\u1e87\u1e88\u1e89]",x:"[x\u1e8c\u1e8d\u1e8a\u1e8b\u03c7]",y:"[y\xdd\xfd\u1ef2\u1ef3\u0176\u0177\u0178\xff\u1ef8\u1ef9\u1e8e\u1e8f\u1ef4\u1ef5\u024e\u024f\u01b3\u01b4]",z:"[z\u0179\u017a\u1e90\u1e91\u017d\u017e\u017b\u017c\u1e92\u1e93\u1e94\u1e95\u01b5\u01b6]"};var asciifold=function(){var r,t,e,i;var n="";var o={};for(e in DIACRITICS){if(DIACRITICS.hasOwnProperty(e)){i=DIACRITICS[e].substring(2,DIACRITICS[e].length-1);n+=i;for(r=0,t=i.length;r<t;r++){o[i.charAt(r)]=e}}}var f=new RegExp("["+n+"]","g");return function(r){return r.replace(f,function(r){return o[r]}).toLowerCase()}}();function cmp(r,t){if(typeof r==="number"&&typeof t==="number"){return r>t?1:r<t?-1:0}r=asciifold(String(r||""));t=asciifold(String(t||""));if(r>t)return 1;if(t>r)return-1;return 0}function extend(r,t){var e,i,n,o;for(e=1,i=arguments.length;e<i;e++){o=arguments[e];if(!o)continue;for(n in o){if(o.hasOwnProperty(n)){r[n]=o[n]}}}return r}function getattr(r,t,e){if(!r||!t)return;if(!e)return r[t];var i=t.split(".");while(i.length&&(r=r[i.shift()]));return r}function trim(r){return(r+"").replace(/^\s+|\s+$|/g,"")}function escapeRegex(r){return(r+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}const isArray=Array.isArray||typeof $!=="undefined"&&$.isArray||function(r){return Object.prototype.toString.call(r)==="[object Array]"};function Sifter(r,t){this.items=r;this.settings=t||{diacritics:true}}Sifter.prototype.tokenize=function(r){r=trim(String(r||"").toLowerCase());if(!r||!r.length)return[];var t,e,i,n;var o=[];var f=r.split(/ +/);for(t=0,e=f.length;t<e;t++){i=escapeRegex(f[t]);if(this.settings.diacritics){for(n in DIACRITICS){if(DIACRITICS.hasOwnProperty(n)){i=i.replace(new RegExp(n,"g"),DIACRITICS[n])}}}o.push({string:f[t],regex:new RegExp(i,"i")})}return o};Sifter.prototype.iterator=function(r,t){var e;if(isArray(r)){e=Array.prototype.forEach||function(r){for(var t=0,e=this.length;t<e;t++){r(this[t],t,this)}}}else{e=function(r){for(var t in this){if(this.hasOwnProperty(t)){r(this[t],t,this)}}}}e.apply(r,[t])};Sifter.prototype.getScoreFunction=function(r,t){var e,i,n,o,f;e=this;r=e.prepareSearch(r,t);n=r.tokens;i=r.options.fields;o=n.length;f=r.options.nesting;function s(r,t){var e,i;if(!r)return 0;r=String(r||"");i=r.search(t.regex);if(i===-1)return 0;e=t.string.length/r.length;if(i===0)e+=.5;return e}var u=function(){var r=i.length;if(!r){return function(){return 0}}if(r===1){return function(r,t){return s(getattr(t,i[0],f),r)}}return function(t,e){for(var n=0,o=0;n<r;n++){o+=s(getattr(e,i[n],f),t)}return o/r}}();if(!o){return function(){return 0}}if(o===1){return function(r){return u(n[0],r)}}if(r.options.conjunction==="and"){return function(r){var t;for(var e=0,i=0;e<o;e++){t=u(n[e],r);if(t<=0)return 0;i+=t}return i/o}}else{return function(r){for(var t=0,e=0;t<o;t++){e+=u(n[t],r)}return e/o}}};Sifter.prototype.getSortFunction=function(r,t){var e,i,n,o,f,s,u,a,c,p;n=this;r=n.prepareSearch(r,t);c=!r.query&&t.sortEmpty||t.sort;function l(r,e){if(r==="$score")return e.score;return getattr(n.items[e.id],r,t.nesting)}f=[];if(c){for(e=0,i=c.length;e<i;e++){if(r.query||c[e].field!=="$score"){f.push(c[e])}}}if(r.query){p=true;for(e=0,i=f.length;e<i;e++){if(f[e].field==="$score"){p=false;break}}if(p){f.unshift({field:"$score",direction:"desc"})}}else{for(e=0,i=f.length;e<i;e++){if(f[e].field==="$score"){f.splice(e,1);break}}}a=[];for(e=0,i=f.length;e<i;e++){a.push(f[e].direction==="desc"?-1:1)}s=f.length;if(!s){return null}else if(s===1){o=f[0].field;u=a[0];return function(r,t){return u*cmp(l(o,r),l(o,t))}}else{return function(r,t){var e,i,n;for(e=0;e<s;e++){n=f[e].field;i=a[e]*cmp(l(n,r),l(n,t));if(i)return i}return 0}}};Sifter.prototype.prepareSearch=function(r,t){if(typeof r==="object")return r;t=extend({},t);var e=t.fields;var i=t.sort;var n=t.sortEmpty;if(e&&!isArray(e))t.fields=[e];if(i&&!isArray(i))t.sort=[i];if(n&&!isArray(n))t.sortEmpty=[n];return{options:t,query:String(r||"").toLowerCase(),tokens:this.tokenize(r),total:0,items:[]}};Sifter.prototype.search=function(r,t){var e=this,i,n;var o;var f;n=this.prepareSearch(r,t);t=n.options;r=n.query;f=t.score||e.getScoreFunction(n);if(r.length){e.iterator(e.items,function(r,e){i=f(r);if(t.filter===false||i>0){n.items.push({score:i,id:e})}})}else{e.iterator(e.items,function(r,t){n.items.push({score:1,id:t})})}o=e.getSortFunction(n,t);if(o)n.items.sort(o);n.total=n.items.length;if(typeof t.limit==="number"){n.items=n.items.slice(0,t.limit)}return n};module.exports=Sifter;