Comparing version 1.2.2 to 1.3.0
{ | ||
"name": "fuse.js", | ||
"version": "1.2.2", | ||
"main": "./src/fuse.js" | ||
} | ||
"version": "1.3.0", | ||
"main": "./src/fuse.js", | ||
"ignore": [ | ||
"test" | ||
] | ||
} |
{ | ||
"name": "fuse.js", | ||
"author": "Kirollos Risk", | ||
"version": "1.2.2", | ||
"version": "1.3.0", | ||
"description": "Lightweight fuzzy-search", | ||
@@ -6,0 +6,0 @@ "license": "Apache", |
@@ -0,4 +1,8 @@ | ||
*Update: There are plenty of enhancements that need to be done to this library. There's more work than available time for me; so if you're interested in being one of the core contributors and helping out, let's talk!* | ||
Fuse | ||
==== | ||
[![NPM](https://nodei.co/npm/fuse.js.png?downloads=true)](https://nodei.co/npm/fuse.js/) | ||
[![Build Status](https://secure.travis-ci.org/krisk/Fuse.png?branch=master)](http://travis-ci.org/krisk/Fuse) | ||
@@ -42,5 +46,5 @@ | ||
**includeScore** (*type*: `Boolean`, *default*: `false`) | ||
**include** (*type*: `Array`, *default*: `[]`) | ||
Whether the score should be included in the result set. When `true`, each result in the list will be of the form `{ item: ..., score: ... }` | ||
An array of values that should be included from the searcher's output. When this array contains elements, each result in the list will be of the form `{ item: ..., include1: ..., include2: ... }`. For example, to include the score, you would set include to ['score'], and the result would be `{ item: ..., score: ... }` | ||
@@ -122,2 +126,18 @@ --- | ||
## Methods | ||
**search(pattern)** | ||
@param {String} pattern The pattern string to fuzzy search on. | ||
@return {Array} A list of all serch matches. | ||
Searches for all the items whose keys (fuzzy) match the pattern. | ||
**set(list)** | ||
@param {Array} list | ||
@return {Array} The newly set list | ||
Sets a new list for Fuse to match against. | ||
## Contributing to Fuse | ||
@@ -124,0 +144,0 @@ |
@@ -291,3 +291,3 @@ /** | ||
// Add boolean type options | ||
for (i = 0, keys = ['sort', 'includeScore', 'shouldSort'], len = keys.length; i < len; i++) { | ||
for (i = 0, keys = ['sort', 'shouldSort'], len = keys.length; i < len; i++) { | ||
key = keys[i]; | ||
@@ -297,3 +297,3 @@ this.options[key] = key in options ? options[key] : Fuse.defaultOptions[key]; | ||
// Add all other options | ||
for (i = 0, keys = ['searchFn', 'sortFn', 'keys', 'getFn'], len = keys.length; i < len; i++) { | ||
for (i = 0, keys = ['searchFn', 'sortFn', 'keys', 'getFn', 'include'], len = keys.length; i < len; i++) { | ||
key = keys[i]; | ||
@@ -309,5 +309,6 @@ this.options[key] = options[key] || Fuse.defaultOptions[key]; | ||
// Whether the score should be included in the result set. | ||
// When <true>, each result in the list will be of the form: `{ item: ..., score: ... }` | ||
includeScore: 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: ... }` | ||
include: [], | ||
@@ -343,2 +344,14 @@ // Whether to sort the result list, by score | ||
/** | ||
* Sets a new list for Fuse to match against. | ||
* @param {Array} list | ||
* @return {Array} The newly set list | ||
* @public | ||
*/ | ||
Fuse.prototype.set = function(list) { | ||
this.list = list; | ||
return list; | ||
}; | ||
/** | ||
* Searches for all the items whose keys (fuzzy) match the pattern. | ||
@@ -431,11 +444,2 @@ * @param {String} pattern The pattern string to fuzzy search on. | ||
// Helper function, here for speed-up, which returns the | ||
// the raw item, including the score, or simply the item itself, depending | ||
// on the specified option | ||
var getItem = options.includeScore ? function(i) { | ||
return rawResults[i]; | ||
} : function(i) { | ||
return rawResults[i].item; | ||
}; | ||
// Helper function, here for speed-up, which replaces the item with its value, | ||
@@ -449,2 +453,28 @@ // if the options specifies it, | ||
// Helper function, here for speed-up, which returns the | ||
// item formatted based on the options. | ||
var getItem = function(i) { | ||
var resultItem; | ||
if(options.include.length > 0) // If `include` has values, put the item under result.item | ||
{ | ||
resultItem = { | ||
item: rawResults[i].item, | ||
}; | ||
// Then include the includes | ||
for(var i = 0; i < options.include.length; i++) | ||
{ | ||
var includeVal = options.include[i]; | ||
resultItem[includeVal] = rawResults[i][includeVal]; | ||
} | ||
} | ||
else | ||
{ | ||
resultItem = rawResults[i].item; | ||
} | ||
return resultItem; | ||
}; | ||
// From the results, push into a new array only the item identifier (if specified) | ||
@@ -454,3 +484,2 @@ // of the entire item. This is because we don't want to return the <rawResults>, | ||
for (var i = 0, len = rawResults.length; i < len; i++) { | ||
// replace the item with its value, which can be its id if the options specifies it | ||
replaceValue(i); | ||
@@ -479,2 +508,2 @@ results.push(getItem(i)); | ||
})(this); | ||
})(this); |
@@ -20,2 +20,2 @@ /** | ||
*/ | ||
!function(t){function e(t,n){this.list=t,this.options=n=n||{};var i,o,s,r;for(i=0,r=["sort","includeScore","shouldSort"],o=r.length;o>i;i++)s=r[i],this.options[s]=s in n?n[s]:e.defaultOptions[s];for(i=0,r=["searchFn","sortFn","keys","getFn"],o=r.length;o>i;i++)s=r[i],this.options[s]=n[s]||e.defaultOptions[s]}var n=function(t,e){if(e=e||{},this.options=e,this.options.location=e.location||n.defaultOptions.location,this.options.distance="distance"in e?e.distance:n.defaultOptions.distance,this.options.threshold="threshold"in e?e.threshold:n.defaultOptions.threshold,this.options.maxPatternLength=e.maxPatternLength||n.defaultOptions.maxPatternLength,this.pattern=e.caseSensitive?t:t.toLowerCase(),this.patternLen=t.length,this.patternLen>this.options.maxPatternLength)throw new Error("Pattern length is too long");this.matchmask=1<<this.patternLen-1,this.patternAlphabet=this._calculatePatternAlphabet()};n.defaultOptions={location:0,distance:100,threshold:.6,maxPatternLength:32},n.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},n.prototype._bitapScore=function(t,e){var n=t/this.patternLen,i=Math.abs(this.options.location-e);return this.options.distance?n+i/this.options.distance:i?1:n},n.prototype.search=function(t){if(t=this.options.caseSensitive?t:t.toLowerCase(),this.pattern===t)return{isMatch:!0,score:0};var e,n,i,o,s,r,a,h,p,c=t.length,l=this.options.location,f=this.options.threshold,u=t.indexOf(this.pattern,l),d=this.patternLen+c,g=1,m=[];for(-1!=u&&(f=Math.min(this._bitapScore(0,u),f),u=t.lastIndexOf(this.pattern,l+this.patternLen),-1!=u&&(f=Math.min(this._bitapScore(0,u),f))),u=-1,e=0;e<this.patternLen;e++){for(i=0,o=d;o>i;)this._bitapScore(e,l+o)<=f?i=o:d=o,o=Math.floor((d-i)/2+i);for(d=o,s=Math.max(1,l-o+1),r=Math.min(l+o,c)+this.patternLen,a=Array(r+2),a[r+1]=(1<<e)-1,n=r;n>=s;n--)if(p=this.patternAlphabet[t.charAt(n-1)],a[n]=0===e?(a[n+1]<<1|1)&p:(a[n+1]<<1|1)&p|((h[n+1]|h[n])<<1|1)|h[n+1],a[n]&this.matchmask&&(g=this._bitapScore(e,n-1),f>=g)){if(f=g,u=n-1,m.push(u),!(u>l))break;s=Math.max(1,2*l-u)}if(this._bitapScore(e+1,l)>f)break;h=a}return{isMatch:u>=0,score:g}};var i=function(t,e,n){var s,r,a;if(e){a=e.indexOf("."),-1!==a?(s=e.slice(0,a),r=e.slice(a+1)):s=e;var h=t[s];if(h)if(r||"string"!=typeof h&&"number"!=typeof h)if(o.isArray(h))for(var p=0,c=h.length;c>p;p++)i(h[p],r,n);else r&&i(h,r,n);else n.push(h)}else n.push(t);return n},o={deepValue:function(t,e){return i(t,e,[])},isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)}};e.defaultOptions={id:null,caseSensitive:!1,includeScore:!1,shouldSort:!0,searchFn:n,sortFn:function(t,e){return t.score-e.score},getFn:o.deepValue,keys:[]},e.prototype.search=function(t){var e,n,i,s,r=new this.options.searchFn(t,this.options),a=this.list,h=a.length,p=this.options,c=this.options.keys,l=c.length,f=[],u={},d=[],g=function(t,e,n){if(void 0!==t&&null!==t)if("string"==typeof t)i=r.search(t),i.isMatch&&(s=u[n],s?s.score=Math.min(s.score,i.score):(u[n]={item:e,score:i.score},f.push(u[n])));else if(o.isArray(t))for(var a=0;a<t.length;a++)g(t[a],e,n)};if("string"==typeof a[0])for(var m=0;h>m;m++)g(a[m],m,m);else for(var m=0;h>m;m++)for(n=a[m],e=0;l>e;e++)g(p.getFn(n,c[e]),n,m);p.shouldSort&&f.sort(p.sortFn);for(var y=p.includeScore?function(t){return f[t]}:function(t){return f[t].item},v=p.id?function(t){f[t].item=p.getFn(f[t].item,p.id)[0]}:function(){},m=0,b=f.length;b>m;m++)v(m),d.push(y(m));return d},"object"==typeof exports?module.exports=e:"function"==typeof define&&define.amd?define(function(){return e}):t.Fuse=e}(this); | ||
!function(t){function e(t,n){this.list=t,this.options=n=n||{};var i,o,s,r;for(i=0,r=["sort","shouldSort"],o=r.length;o>i;i++)s=r[i],this.options[s]=s in n?n[s]:e.defaultOptions[s];for(i=0,r=["searchFn","sortFn","keys","getFn","include"],o=r.length;o>i;i++)s=r[i],this.options[s]=n[s]||e.defaultOptions[s]}var n=function(t,e){if(e=e||{},this.options=e,this.options.location=e.location||n.defaultOptions.location,this.options.distance="distance"in e?e.distance:n.defaultOptions.distance,this.options.threshold="threshold"in e?e.threshold:n.defaultOptions.threshold,this.options.maxPatternLength=e.maxPatternLength||n.defaultOptions.maxPatternLength,this.pattern=e.caseSensitive?t:t.toLowerCase(),this.patternLen=t.length,this.patternLen>this.options.maxPatternLength)throw new Error("Pattern length is too long");this.matchmask=1<<this.patternLen-1,this.patternAlphabet=this._calculatePatternAlphabet()};n.defaultOptions={location:0,distance:100,threshold:.6,maxPatternLength:32},n.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},n.prototype._bitapScore=function(t,e){var n=t/this.patternLen,i=Math.abs(this.options.location-e);return this.options.distance?n+i/this.options.distance:i?1:n},n.prototype.search=function(t){if(t=this.options.caseSensitive?t:t.toLowerCase(),this.pattern===t)return{isMatch:!0,score:0};var e,n,i,o,s,r,a,h,p,c=t.length,l=this.options.location,f=this.options.threshold,u=t.indexOf(this.pattern,l),d=this.patternLen+c,g=1,m=[];for(-1!=u&&(f=Math.min(this._bitapScore(0,u),f),u=t.lastIndexOf(this.pattern,l+this.patternLen),-1!=u&&(f=Math.min(this._bitapScore(0,u),f))),u=-1,e=0;e<this.patternLen;e++){for(i=0,o=d;o>i;)this._bitapScore(e,l+o)<=f?i=o:d=o,o=Math.floor((d-i)/2+i);for(d=o,s=Math.max(1,l-o+1),r=Math.min(l+o,c)+this.patternLen,a=Array(r+2),a[r+1]=(1<<e)-1,n=r;n>=s;n--)if(p=this.patternAlphabet[t.charAt(n-1)],a[n]=0===e?(a[n+1]<<1|1)&p:(a[n+1]<<1|1)&p|((h[n+1]|h[n])<<1|1)|h[n+1],a[n]&this.matchmask&&(g=this._bitapScore(e,n-1),f>=g)){if(f=g,u=n-1,m.push(u),!(u>l))break;s=Math.max(1,2*l-u)}if(this._bitapScore(e+1,l)>f)break;h=a}return{isMatch:u>=0,score:g}};var i=function(t,e,n){var s,r,a;if(e){a=e.indexOf("."),-1!==a?(s=e.slice(0,a),r=e.slice(a+1)):s=e;var h=t[s];if(h)if(r||"string"!=typeof h&&"number"!=typeof h)if(o.isArray(h))for(var p=0,c=h.length;c>p;p++)i(h[p],r,n);else r&&i(h,r,n);else n.push(h)}else n.push(t);return n},o={deepValue:function(t,e){return i(t,e,[])},isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)}};e.defaultOptions={id:null,caseSensitive:!1,include:[],shouldSort:!0,searchFn:n,sortFn:function(t,e){return t.score-e.score},getFn:o.deepValue,keys:[]},e.prototype.set=function(t){return this.list=t,t},e.prototype.search=function(t){var e,n,i,s,r=new this.options.searchFn(t,this.options),a=this.list,h=a.length,p=this.options,c=this.options.keys,l=c.length,f=[],u={},d=[],g=function(t,e,n){if(void 0!==t&&null!==t)if("string"==typeof t)i=r.search(t),i.isMatch&&(s=u[n],s?s.score=Math.min(s.score,i.score):(u[n]={item:e,score:i.score},f.push(u[n])));else if(o.isArray(t))for(var a=0;a<t.length;a++)g(t[a],e,n)};if("string"==typeof a[0])for(var m=0;h>m;m++)g(a[m],m,m);else for(var m=0;h>m;m++)for(n=a[m],e=0;l>e;e++)g(p.getFn(n,c[e]),n,m);p.shouldSort&&f.sort(p.sortFn);for(var v=p.id?function(t){f[t].item=p.getFn(f[t].item,p.id)[0]}:function(){},y=function(t){var e;if(p.include.length>0){e={item:f[t].item};for(var t=0;t<p.include.length;t++){var n=p.include[t];e[n]=f[t][n]}}else e=f[t].item;return e},m=0,b=f.length;b>m;m++)v(m),d.push(y(m));return d},"object"==typeof exports?module.exports=e:"function"==typeof define&&define.amd?define(function(){return e}):t.Fuse=e}(this); |
@@ -237,3 +237,3 @@ var assert = require('assert'), | ||
var fuse = new Fuse(fruits, { | ||
includeScore: true | ||
include: ['score'] | ||
}); | ||
@@ -322,3 +322,3 @@ return fuse; | ||
id: "ISBN", | ||
includeScore: true | ||
include: ['score'] | ||
} | ||
@@ -361,3 +361,3 @@ var fuse = new Fuse(books, options) | ||
id: "ISBN", | ||
includeScore: true | ||
include: ['score'] | ||
} | ||
@@ -511,3 +511,3 @@ var fuse = new Fuse(books, options) | ||
'whose value is the ISBN of the book': function(result) { | ||
assert.isString(result[0]) | ||
assert.isString(result[0]); | ||
assert.equal(result[0], "B"); | ||
@@ -519,2 +519,27 @@ }, | ||
vows.describe('Set new list on Fuse').addBatch({ | ||
'Options:': { | ||
topic: function() { | ||
var fruits = ["Apple", "Orange", "Banana"]; | ||
var vegetables = ["Onion", "Lettuce", "Broccoli"]; | ||
var fuse = new Fuse(fruits); | ||
fuse.set(vegetables); | ||
return fuse; | ||
}, | ||
'When searching for the term "Apple"': { | ||
topic: function(fuse) { | ||
var result = fuse.search("Lettuce"); | ||
return result; | ||
}, | ||
'we get a list of containing 1 item, which is an exact match': function(result) { | ||
assert.equal(result.length, 1); | ||
}, | ||
'whose value is the index 0, representing ["Lettuce"]': function(result) { | ||
assert.equal(result[0], 1); | ||
}, | ||
} | ||
} | ||
}).export(module); | ||
vows.describe('Searching by nested ID').addBatch({ | ||
@@ -521,0 +546,0 @@ 'Options:': { |
Sorry, the diff of this file is not supported yet
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
1992864
88443
146