Skip to content

farzher/fuzzysort

Repository files navigation

fuzzysort

Fast, Tiny, & Good fuzzy search for JavaScript.

Fast:<1msto search13,000files.
Tiny:1 file,0 dependencies,5kb.
Good:clean api + sorts results well.

https://rawgit /farzher/fuzzysort/master/test/test.html

Installation Node / Bun / Deno

npm i fuzzysort
importfuzzysortfrom'fuzzysort'
constfuzzysort=require('fuzzysort')

Installation Browser

<scriptsrc= "https://cdn.jsdelivr.net/npm/[email protected]/fuzzysort.min.js"></script>

Usage

fuzzysort.go(search, targets, options=null)

constmystuff=[{file:'Apple.cpp'},{file:'Banana.cpp'}]
constresults=fuzzysort.go('a',mystuff,{key:'file'})
// [{score: 0.81, obj: {file: 'Apple.cpp'}}, {score: 0.59, obj: {file: 'Banana.cpp'}}]

Options

fuzzysort.go(search,targets,{
threshold:0,// Don't return matches worse than this
limit:0,// Don't return more results than this
all:false,// If true, returns all results for an empty search

key:null,// For when targets are objects (see its example usage)
keys:null,// For when targets are objects (see its example usage)
scoreFn:null,// For use with `keys` (see its example usage)
})

What's aresult

constresult=fuzzysort.single('query','some string that contains my query.')
result.score//.80 (1 is a perfect match. 0.5 is a good match. 0 is no match.)
result.target// 'some string that contains my query.'
result.obj// reference to your original obj when using options.key
result.indexes// [29, 30, 31, 32, 33]

result.highlight('<b>','</b>')
// 'some string that contains my <b>query</b>.'

result.highlight((m,i)=><reactkey={i}>{m}</react>)
// ['some string that contains my ', <react key=0>query</react>, '.']

Advanced Usage

Search a list of objects, by multiple complex keys, with custom weights.

letobjects=[{
title:'Liechi Berry',
meta:{desc:'Raises Attack when HP is low.'},
tags:['berries','items'],
bookmarked:true,
},{
title:'Petaya Berry',
meta:{desc:'Raises Special Attack when HP is low.'},
}]

letresults=fuzzysort.go('attack berry',objects,{
keys:['title','meta.desc',obj=>obj.tags?.join()],
scoreFn:r=>r.score*r.obj.bookmarked?2:1,// if the item is bookmarked, boost its score
})

varkeysResult=results[0]
// When using multiple `keys`, results are different. They're indexable to get each normal result
keysResult[0].highlight()// 'Liechi <b>Berry</b>'
keysResult[1].highlight()// 'Raises <b>Attack</b> when HP is low.'
keysResult.score//.84
keysResult.obj.title// 'Liechi Berry'

How To Go Fast · Performance Tips

lettargets=[{file:'Monitor.cpp'},{file:'MeshRenderer.cpp'}]

// filter out targets that you don't need to search! especially long ones!
targets=targets.filter(t=>t.file.length<1000)

// if your targets don't change often, provide prepared targets instead of raw strings!
targets.forEach(t=>t.filePrepared=fuzzysort.prepare(t.file))

// don't use options.key if you don't need a reference to your original obj
targets=targets.map(t=>t.filePrepared)

constoptions={
limit:100,// don't return more results than you need!
threshold:.5,// don't return bad results
}
fuzzysort.go('gotta',targets,options)
fuzzysort.go('go',targets,options)
fuzzysort.go('fast',targets,options)

Gotcha

result.scoreis implemented as a getter/setter and stored different internally r.score =.3; // r.score == 0.30000000000000004

Star History

Star History Chart

Changelog

v3.1.0

  • Automatically handle diacritics / accents / ligatures

v3.0.0

  • Added new behavior when usingkeysand your search contains spaces!
  • Addedoptions.keycan now be a function{key: obj => obj.tags.join()}
  • Removedfuzzysort.indexes& Addedresult.indexes(as a getter/setter for GC perf)
  • Removedfuzzysort.highlight()& Addedresult.highlight()
  • Changed scoring: score is now a number from 0 to 1 instead of from -Infinity to 0
  • Changed scoring: substring matches are even more relevant
  • Changed scoring:straw berrynow matches great againststrawberry
  • Changed scoring: tweaked the scoring quite a bit
  • result.scoreis behind a getter/setter for performance reasons
  • Fixed minor issues

v2.0.0

  • Added new behavior when your search contains spaces!
  • Added fuzzysort.min.js
  • Now depends on ES6 features
  • Removedresult.indexes& Addedfuzzysort.indexes(improved GC performance)
  • Completely Removedoptions.allowTypo
  • Completely Removedfuzzysort.goAsync
  • Completely Removedfuzzysort.new
  • Rewrote the demo

v1.9.0

  • Even faster
  • Addedoptions.all
  • Deprecated/Removedoptions.allowTypo
  • Deprecated/Removedfuzzysort.goAsync
  • Changed scoring: boosted substring matches
  • Changed scoring: targets with too many beginning indexes lose points for being a bad target
  • Changed scoring: penality for not starting near the beginning
  • Changed scoring: penality for more groups
  • Fixed "Exponential backtracking hangs browser"

v1.2.0

  • Addedfuzzysort.highlight(result, callback)

v1.1.0

  • AddedallowTypoas an option

v1.0.0

  • Inverted scores; they're now negative instead of positive, so that higher scores are better
  • Added ability to search objects bykey/keyswith custom weights
  • Removed the option to automatically highlight and exposedfuzzysort.highlight
  • Removed all options fromfuzzysortand moved them intofuzzysort.gooptional params

v0.x.x

  • init