Comparing version 2.0.1 to 2.0.2
{ | ||
"name": "fuse.js", | ||
"version": "2.0.1", | ||
"version": "2.0.2", | ||
"main": "./src/fuse.js", | ||
@@ -5,0 +5,0 @@ "ignore": [ |
{ | ||
"name": "fuse.js", | ||
"author": "Kirollos Risk", | ||
"version": "2.0.1", | ||
"version": "2.0.2", | ||
"description": "Lightweight fuzzy-search", | ||
@@ -6,0 +6,0 @@ "license": "Apache", |
@@ -128,2 +128,8 @@ # Fuse | ||
--- | ||
**tokenize** (*type*: `Boolean`, *default*: `false`) | ||
When true, the search algorithm will search individual words **and** the full string, computing the final score as a function of both. Note that when `tokenize` is `true`, the `threshold`, `distance`, and `location` are inconsequential for individual tokens. | ||
## Methods | ||
@@ -130,0 +136,0 @@ |
@@ -30,8 +30,13 @@ /** | ||
var defaultOptions = { | ||
// The name of the identifier property. If specified, the returned result will be a list | ||
// of the items' dentifiers, otherwise it will be a list of the items. | ||
id: null, | ||
// Indicates whether comparisons should be case sensitive. | ||
caseSensitive: false, | ||
// A list of values to be passed from the searcher to the result set. | ||
// If include is set to ['score', 'highlight'], each result | ||
// in the list will be of the form: `{ item: ..., score: ..., highlight: ... }` | ||
// If include is set to ['score', 'highlight'], each result in the list will be | ||
// of the form: `{ item: ..., score: ... }` | ||
include: [], | ||
@@ -61,8 +66,16 @@ | ||
// Default get function | ||
// The get function to use when fetching an object's properties. | ||
// The default will search nested paths *ie foo.bar.baz* | ||
getFn: deepValue, | ||
// List of properties that will be searched. This also supports nested properties. | ||
keys: [], | ||
verbose: false | ||
// Will print to the console. Useful for debugging. | ||
verbose: false, | ||
// When true, the search algorithm will search individual words **and** the full string, | ||
// computing the final score as a function of both. Note that when `tokenize` is `true`, | ||
// the `threshold`, `distance`, and `location` are inconsequential for individual tokens. | ||
tokenize: false | ||
} | ||
@@ -80,3 +93,3 @@ | ||
// Add boolean type options | ||
for (i = 0, keys = ['sort', 'shouldSort', 'verbose'], len = keys.length; i < len; i++) { | ||
for (i = 0, keys = ['sort', 'shouldSort', 'verbose', 'tokenize'], len = keys.length; i < len; i++) { | ||
key = keys[i] | ||
@@ -129,6 +142,7 @@ this.options[key] = key in options ? options[key] : defaultOptions[key] | ||
this.tokenSearchers = [] | ||
for (; i < len; i++) { | ||
this.tokenSearchers.push(new searchFn(tokens[i], options)) | ||
if (this.options.tokenize) { | ||
this.tokenSearchers = [] | ||
for (; i < len; i++) { | ||
this.tokenSearchers.push(new searchFn(tokens[i], options)) | ||
} | ||
} | ||
@@ -175,4 +189,4 @@ this.fullSeacher = new searchFn(pattern, options) | ||
var exists = false | ||
var tokenSearchers = this.tokenSearchers | ||
var tokenSearchersLen = tokenSearchers.length | ||
var tokenSearchers | ||
var tokenSearchersLen | ||
var existingResult | ||
@@ -202,29 +216,35 @@ var averageScore | ||
for (i = 0; i < this.tokenSearchers.length; i++) { | ||
tokenSearcher = this.tokenSearchers[i] | ||
termScores = [] | ||
for (j = 0; j < words.length; j++) { | ||
word = words[j] | ||
tokenSearchResult = tokenSearcher.search(word) | ||
if (tokenSearchResult.isMatch) { | ||
exists = true | ||
termScores.push(tokenSearchResult.score) | ||
scores.push(tokenSearchResult.score) | ||
} else { | ||
termScores.push(1) | ||
scores.push(1) | ||
if (this.options.tokenize) { | ||
tokenSearchers = this.tokenSearchers | ||
tokenSearchersLen = tokenSearchers.length | ||
for (i = 0; i < this.tokenSearchers.length; i++) { | ||
tokenSearcher = this.tokenSearchers[i] | ||
termScores = [] | ||
for (j = 0; j < words.length; j++) { | ||
word = words[j] | ||
tokenSearchResult = tokenSearcher.search(word) | ||
if (tokenSearchResult.isMatch) { | ||
exists = true | ||
termScores.push(tokenSearchResult.score) | ||
scores.push(tokenSearchResult.score) | ||
} else { | ||
termScores.push(1) | ||
scores.push(1) | ||
} | ||
} | ||
if (options.verbose) log('Score for "' + tokenSearcher.pattern + '":', termScores) | ||
} | ||
if (options.verbose) log('Score for "' + tokenSearcher.pattern + '":', termScores) | ||
} | ||
averageScore = scores[0] | ||
scoresLen = scores.length | ||
for (i = 1; i < scoresLen; i++) { | ||
averageScore += scores[i] | ||
averageScore = scores[0] | ||
scoresLen = scores.length | ||
for (i = 1; i < scoresLen; i++) { | ||
averageScore += scores[i] | ||
} | ||
averageScore = averageScore / scoresLen | ||
if (options.verbose) log('Individual word score average:', averageScore) | ||
} | ||
averageScore = averageScore / scoresLen | ||
if (options.verbose) log('Individual word score average:', averageScore) | ||
// Get the result | ||
@@ -592,4 +612,3 @@ mainSearchResult = this.fullSeacher.search(text) | ||
if (bitArr[j] & this.matchmask) { | ||
// Count exact matches (those with a score of 0) to be "almost" exact | ||
score = this._bitapScore(i, j - 1) || 0.001 | ||
score = this._bitapScore(i, j - 1) | ||
@@ -622,5 +641,6 @@ // This match will almost certainly be better than any existing match. | ||
// Count exact matches (those with a score of 0) to be "almost" exact | ||
return { | ||
isMatch: bestLoc >= 0, | ||
score: score | ||
score: score === 0 ? 0.001 : score | ||
} | ||
@@ -627,0 +647,0 @@ } |
@@ -20,2 +20,2 @@ /** | ||
*/ | ||
!function(t){"use strict";function e(){console.log.apply(console,arguments)}function s(t,e){var s,r,n,o;for(this.list=t,this.options=e=e||{},s=0,o=["sort","shouldSort","verbose"],r=o.length;r>s;s++)n=o[s],this.options[n]=n in e?e[n]:h[n];for(s=0,o=["searchFn","sortFn","keys","getFn","include"],r=o.length;r>s;s++)n=o[s],this.options[n]=e[n]||h[n]}function r(t,e,s){var o,i,h,a,p,c;if(e){if(h=e.indexOf("."),-1!==h?(o=e.slice(0,h),i=e.slice(h+1)):o=e,a=t[o],null!==a&&void 0!==a)if(i||"string"!=typeof a&&"number"!=typeof a)if(n(a))for(p=0,c=a.length;c>p;p++)r(a[p],i,s);else i&&r(a,i,s);else s.push(a)}else s.push(t);return s}function n(t){return"[object Array]"===Object.prototype.toString.call(t)}function o(t,e){e=e||{},this.options=e,this.options.location=e.location||o.defaultOptions.location,this.options.distance="distance"in e?e.distance:o.defaultOptions.distance,this.options.threshold="threshold"in e?e.threshold:o.defaultOptions.threshold,this.options.maxPatternLength=e.maxPatternLength||o.defaultOptions.maxPatternLength,this.pattern=e.caseSensitive?t:t.toLowerCase(),this.patternLen=t.length,this.patternLen<=this.options.maxPatternLength&&(this.matchmask=1<<this.patternLen-1,this.patternAlphabet=this._calculatePatternAlphabet())}var i=/ +/g,h={id:null,caseSensitive:!1,include:[],shouldSort:!0,searchFn:o,sortFn:function(t,e){return t.score-e.score},getFn:r,keys:[],verbose:!1};s.VERSION="2.0.1",s.prototype.set=function(t){return this.list=t,t},s.prototype.search=function(t){this.options.verbose&&e("=====================\n","Search term:",t),this.pattern=t,this.results=[],this.resultMap={},this._prepareSearchers(),this._startSearch(),this._computeScore(),this._sort();var s=this._format();return s},s.prototype._prepareSearchers=function(){var t=this.options,e=this.pattern,s=t.searchFn,r=e.split(i),n=0,o=r.length;for(this.tokenSearchers=[];o>n;n++)this.tokenSearchers.push(new s(r[n],t));this.fullSeacher=new s(e,t)},s.prototype._startSearch=function(){var t,e,s=this.options,r=s.getFn,n=this.list,o=n.length,i=this.options.keys,h=i.length,a=null;if("string"==typeof n[0])for(t=0;o>t;t++)this._analyze(n[t],t,t);else for(t=0;o>t;t++)for(a=n[t],e=0;h>e;e++)this._analyze(r(a,i[e],[]),a,t)},s.prototype._analyze=function(t,s,r){var o,h,a,p,c,l,u,f,d,g,v,m,S,y=this.options,b=!1,_=this.tokenSearchers;_.length;if(void 0!==t&&null!==t)if(h=[],"string"==typeof t){for(o=t.split(i),y.verbose&&e("---------\n","Record:",o),m=0;m<this.tokenSearchers.length;m++){for(f=this.tokenSearchers[m],d=[],S=0;S<o.length;S++)g=o[S],v=f.search(g),v.isMatch?(b=!0,d.push(v.score),h.push(v.score)):(d.push(1),h.push(1));y.verbose&&e('Score for "'+f.pattern+'":',d)}for(p=h[0],l=h.length,m=1;l>m;m++)p+=h[m];p/=l,y.verbose&&e("Individual word score average:",p),u=this.fullSeacher.search(t),y.verbose&&e("Full text score:",u.score),c=u.score,void 0!==p&&(c=(c+p)/2),y.verbose&&e("Average",c),(b||u.isMatch)&&(a=this.resultMap[r],a?a.scores.push(c):(this.resultMap[r]={item:s,scores:[c]},this.results.push(this.resultMap[r])))}else if(n(t))for(m=0;m<t.length;m++)this._analyze(t[m],s,r)},s.prototype._computeScore=function(){var t,e,s,r,n,o=this.results;for(t=0;t<o.length;t++){for(s=0,r=o[t].scores,n=r.length,e=0;n>e;e++)s+=r[e];o[t].score=s/n}},s.prototype._sort=function(){var t=this.options;t.shouldSort&&(t.verbose&&e("Sorting...."),this.results.sort(t.sortFn))},s.prototype._format=function(){var t,s,r,n,o,i=this.options,h=i.getFn,a=[],p=this.results;for(i.verbose&&e("------------\n","Output:\n",p),n=i.id?function(t){p[t].item=h(p[t].item,i.id,[])[0]}:function(){},o=function(t){var e,s,r;if(i.include.length>0)for(e={item:p[t].item},r=0;r<i.include.length;r++)s=i.include[r],e[s]=p[t][s];else e=p[t].item;return e},s=0,r=p.length;r>s;s++)n(s),t=o(s),a.push(t);return a},o.defaultOptions={location:0,distance:100,threshold:.6,maxPatternLength:32},o.prototype._calculatePatternAlphabet=function(){var t={},e=0;for(e=0;e<this.patternLen;e++)t[this.pattern.charAt(e)]=0;for(e=0;e<this.patternLen;e++)t[this.pattern.charAt(e)]|=1<<this.pattern.length-e-1;return t},o.prototype._bitapScore=function(t,e){var s=t/this.patternLen,r=Math.abs(this.options.location-e);return this.options.distance?s+r/this.options.distance:r?1:s},o.prototype.search=function(t){var e,s,r,n,o,h,a,p,c,l,u,f,d,g,v,m,S,y,b=this.options;if(t=b.caseSensitive?t:t.toLowerCase(),this.pattern===t)return{isMatch:!0,score:0};if(this.patternLen>b.maxPatternLength)return S=t.match(new RegExp(this.pattern.replace(i,"|"))),y=!!S,{isMatch:y,score:y?.5:1};for(n=b.location,r=t.length,o=b.threshold,h=t.indexOf(this.pattern,n),-1!=h&&(o=Math.min(this._bitapScore(0,h),o),h=t.lastIndexOf(this.pattern,n+this.patternLen),-1!=h&&(o=Math.min(this._bitapScore(0,h),o))),h=-1,v=1,m=[],c=this.patternLen+r,e=0;e<this.patternLen;e++){for(a=0,p=c;p>a;)this._bitapScore(e,n+p)<=o?a=p:c=p,p=Math.floor((c-a)/2+a);for(c=p,l=Math.max(1,n-p+1),u=Math.min(n+p,r)+this.patternLen,f=Array(u+2),f[u+1]=(1<<e)-1,s=u;s>=l;s--)if(g=this.patternAlphabet[t.charAt(s-1)],0===e?f[s]=(f[s+1]<<1|1)&g:f[s]=(f[s+1]<<1|1)&g|((d[s+1]|d[s])<<1|1)|d[s+1],f[s]&this.matchmask&&(v=this._bitapScore(e,s-1)||.001,o>=v)){if(o=v,h=s-1,m.push(h),!(h>n))break;l=Math.max(1,2*n-h)}if(this._bitapScore(e+1,n)>o)break;d=f}return{isMatch:h>=0,score:v}},"object"==typeof exports?module.exports=s:"function"==typeof define&&define.amd?define(function(){return s}):t.Fuse=s}(this); | ||
!function(t){"use strict";function e(){console.log.apply(console,arguments)}function s(t,e){var s,n,r,i;for(this.list=t,this.options=e=e||{},s=0,i=["sort","shouldSort","verbose","tokenize"],n=i.length;n>s;s++)r=i[s],this.options[r]=r in e?e[r]:h[r];for(s=0,i=["searchFn","sortFn","keys","getFn","include"],n=i.length;n>s;s++)r=i[s],this.options[r]=e[r]||h[r]}function n(t,e,s){var i,o,h,a,p,c;if(e){if(h=e.indexOf("."),-1!==h?(i=e.slice(0,h),o=e.slice(h+1)):i=e,a=t[i],null!==a&&void 0!==a)if(o||"string"!=typeof a&&"number"!=typeof a)if(r(a))for(p=0,c=a.length;c>p;p++)n(a[p],o,s);else o&&n(a,o,s);else s.push(a)}else s.push(t);return s}function r(t){return"[object Array]"===Object.prototype.toString.call(t)}function i(t,e){e=e||{},this.options=e,this.options.location=e.location||i.defaultOptions.location,this.options.distance="distance"in e?e.distance:i.defaultOptions.distance,this.options.threshold="threshold"in e?e.threshold:i.defaultOptions.threshold,this.options.maxPatternLength=e.maxPatternLength||i.defaultOptions.maxPatternLength,this.pattern=e.caseSensitive?t:t.toLowerCase(),this.patternLen=t.length,this.patternLen<=this.options.maxPatternLength&&(this.matchmask=1<<this.patternLen-1,this.patternAlphabet=this._calculatePatternAlphabet())}var o=/ +/g,h={id:null,caseSensitive:!1,include:[],shouldSort:!0,searchFn:i,sortFn:function(t,e){return t.score-e.score},getFn:n,keys:[],verbose:!1,tokenize:!1};s.VERSION="2.0.1",s.prototype.set=function(t){return this.list=t,t},s.prototype.search=function(t){this.options.verbose&&e("=====================\n","Search term:",t),this.pattern=t,this.results=[],this.resultMap={},this._prepareSearchers(),this._startSearch(),this._computeScore(),this._sort();var s=this._format();return s},s.prototype._prepareSearchers=function(){var t=this.options,e=this.pattern,s=t.searchFn,n=e.split(o),r=0,i=n.length;if(this.options.tokenize)for(this.tokenSearchers=[];i>r;r++)this.tokenSearchers.push(new s(n[r],t));this.fullSeacher=new s(e,t)},s.prototype._startSearch=function(){var t,e,s=this.options,n=s.getFn,r=this.list,i=r.length,o=this.options.keys,h=o.length,a=null;if("string"==typeof r[0])for(t=0;i>t;t++)this._analyze(r[t],t,t);else for(t=0;i>t;t++)for(a=r[t],e=0;h>e;e++)this._analyze(n(a,o[e],[]),a,t)},s.prototype._analyze=function(t,s,n){var i,h,a,p,c,l,u,f,d,g,v,m,S,y,b,_=this.options,L=!1;if(void 0!==t&&null!==t)if(h=[],"string"==typeof t){if(i=t.split(o),_.verbose&&e("---------\n","Record:",i),this.options.tokenize){for(a=this.tokenSearchers,p=a.length,y=0;y<this.tokenSearchers.length;y++){for(g=this.tokenSearchers[y],v=[],b=0;b<i.length;b++)m=i[b],S=g.search(m),S.isMatch?(L=!0,v.push(S.score),h.push(S.score)):(v.push(1),h.push(1));_.verbose&&e('Score for "'+g.pattern+'":',v)}for(l=h[0],f=h.length,y=1;f>y;y++)l+=h[y];l/=f,_.verbose&&e("Individual word score average:",l)}d=this.fullSeacher.search(t),_.verbose&&e("Full text score:",d.score),u=d.score,void 0!==l&&(u=(u+l)/2),_.verbose&&e("Average",u),(L||d.isMatch)&&(c=this.resultMap[n],c?c.scores.push(u):(this.resultMap[n]={item:s,scores:[u]},this.results.push(this.resultMap[n])))}else if(r(t))for(y=0;y<t.length;y++)this._analyze(t[y],s,n)},s.prototype._computeScore=function(){var t,e,s,n,r,i=this.results;for(t=0;t<i.length;t++){for(s=0,n=i[t].scores,r=n.length,e=0;r>e;e++)s+=n[e];i[t].score=s/r}},s.prototype._sort=function(){var t=this.options;t.shouldSort&&(t.verbose&&e("Sorting...."),this.results.sort(t.sortFn))},s.prototype._format=function(){var t,s,n,r,i,o=this.options,h=o.getFn,a=[],p=this.results;for(o.verbose&&e("------------\n","Output:\n",p),r=o.id?function(t){p[t].item=h(p[t].item,o.id,[])[0]}:function(){},i=function(t){var e,s,n;if(o.include.length>0)for(e={item:p[t].item},n=0;n<o.include.length;n++)s=o.include[n],e[s]=p[t][s];else e=p[t].item;return e},s=0,n=p.length;n>s;s++)r(s),t=i(s),a.push(t);return a},i.defaultOptions={location:0,distance:100,threshold:.6,maxPatternLength:32},i.prototype._calculatePatternAlphabet=function(){var t={},e=0;for(e=0;e<this.patternLen;e++)t[this.pattern.charAt(e)]=0;for(e=0;e<this.patternLen;e++)t[this.pattern.charAt(e)]|=1<<this.pattern.length-e-1;return t},i.prototype._bitapScore=function(t,e){var s=t/this.patternLen,n=Math.abs(this.options.location-e);return this.options.distance?s+n/this.options.distance:n?1:s},i.prototype.search=function(t){var e,s,n,r,i,h,a,p,c,l,u,f,d,g,v,m,S,y,b=this.options;if(t=b.caseSensitive?t:t.toLowerCase(),this.pattern===t)return{isMatch:!0,score:0};if(this.patternLen>b.maxPatternLength)return S=t.match(new RegExp(this.pattern.replace(o,"|"))),y=!!S,{isMatch:y,score:y?.5:1};for(r=b.location,n=t.length,i=b.threshold,h=t.indexOf(this.pattern,r),-1!=h&&(i=Math.min(this._bitapScore(0,h),i),h=t.lastIndexOf(this.pattern,r+this.patternLen),-1!=h&&(i=Math.min(this._bitapScore(0,h),i))),h=-1,v=1,m=[],c=this.patternLen+n,e=0;e<this.patternLen;e++){for(a=0,p=c;p>a;)this._bitapScore(e,r+p)<=i?a=p:c=p,p=Math.floor((c-a)/2+a);for(c=p,l=Math.max(1,r-p+1),u=Math.min(r+p,n)+this.patternLen,f=Array(u+2),f[u+1]=(1<<e)-1,s=u;s>=l;s--)if(g=this.patternAlphabet[t.charAt(s-1)],0===e?f[s]=(f[s+1]<<1|1)&g:f[s]=(f[s+1]<<1|1)&g|((d[s+1]|d[s])<<1|1)|d[s+1],f[s]&this.matchmask&&(v=this._bitapScore(e,s-1),i>=v)){if(i=v,h=s-1,m.push(h),!(h>r))break;l=Math.max(1,2*r-h)}if(this._bitapScore(e+1,r)>i)break;d=f}return{isMatch:h>=0,score:0===v?.001:v}},"object"==typeof exports?module.exports=s:"function"==typeof define&&define.amd?define(function(){return s}):t.Fuse=s}(this); |
@@ -63,3 +63,4 @@ var assert = require('assert'), | ||
keys: ['title', 'author'], | ||
verbose: verbose | ||
verbose: verbose, | ||
tokenize: true | ||
} | ||
@@ -66,0 +67,0 @@ var fuse = new Fuse(books, options) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2002077
88671
163