farzher / fuzzysort Goto Github PK
View Code? Open in Web Editor NEWFast SublimeText-like fuzzy search for JavaScript.
Home Page: https://rawgit.com/farzher/fuzzysort/master/test/test.html
License: MIT License
Fast SublimeText-like fuzzy search for JavaScript.
Home Page: https://rawgit.com/farzher/fuzzysort/master/test/test.html
License: MIT License
Hey there,
I'm getting an issue that produces the following error:
./node_modules/timers-browserify/main.js
Module not found: `~~something on my computer~~~/node_modules/setimmediate/setimmediate.js` does not match the corresponding path on disk `setImmediate.js`.
#facebook/create-react-app/472 mentions the CaseSensitivePathsPlugin, which would seem to be the issue - setimmediate in its own repository doesn't use camelCase, but your usage in the built fuzzysort.js does.
To fix it in a hacky way on my end, I manually went to the built file and changed it in my node_modules, removing the capital 'I' and that fixed the issue.
I haven't looked at the prebuilt code, but I could look at doing a pull-request if I figure it out myself.
Thanks, like the library otherwise!
We are using this to search millions of product descriptions but it returns a large result object foreach product.
If we could do in placr sorting or have it return a simple order int array, it would consume less memory but still allow us to sort results.
Thanks so much, we love the accuracy and speed of the library
I couldn't find the documentation for this library. My requirement iss to search a array of objects. Consider the following object
var cars = [
{ id: 725, value: 'Aston Martin' },
{ id: 123, value: 'Lamborgini' },
{ id: 841, value: 'Viper' },
{ id: 160, value: 'Tesla' },
{ id: 528, value: 'Ferrai' },
{ id: 684, value: 'Mustang' },
{ id: 465, value: 'Volkswagen' },
]
I want to give this object to fuzzysort and a search string and return the object which closely resemble the query
I'm using it like
let query = 'ar'
let results = fuzzysort.go(query, cars, { key: 'value', allowTypo: true, limit: 10 })
This returns the array with two search results for "Lamborgini" and "Aston Martin". But how do I get the index of these results in the cars array using this library. Or should I use map function to try match the ids myself. I will be handling a large object so to find these elements and again search for the index increases the computation power.
Thanks for the library in the first place! Would super appreciate if you could put an example on how to get results between 0 and 1 or in terms of percentage or whatever works
People may want to use this package outside of a browser setting, where HTML tags don't do much.
It would be great if it exposed the match indices so they could be used with e.g. String.prototype.slice
.
How would one match a whole string only?
For example, if the search string is find
only match give the matches which contains the entire find
phrase, not f
, i
, n
and d
combinations.
I tried determining this from the score without much success.
Desired functionality would cover use cases when you want to search the users arrary. The user interface would look for example like:
interface UserModel {
name: string;
email: string;
nick: string;
somethingElse: number;
}
When creating the Prepared
as when using prepare
function you would be able to provide the data object (UserModel
in this example) and the array of the keys that will be considered in the search. In this example ['name', 'email', 'nick']
I am not sure if this is supported somehow and I just didn't find it in readme
Hi.
The library is super fast !!
I was wondering...
On an imaginary dataset, If i try to search for
dog cat
is this the right library to return matches like
doggy category
category doggy
ie 2 matches order agnostic
thanks
It would be really helpful if there was an option to enable mapping all latin extended chars to basic ones.
It would work similarly as when the strings are lowercased before matching. There are plenty helper methods for this like latinize
I'm curious why the first row is ahead of the following three, which seem like better matches in my view (as whole word matches). It looks like it should be under those three, where rows 5, 6, 7 are. Then the bottom result is really a best match, like 2, 3, 4; so it's placement is head-scratching as well.
Hi,
I have implemented fuzzysort on a website with the following options:
var options = {
limit: 10, // don't return more results than you need!
allowTypo: true, // if you don't care about allowing typos
threshold: -10000, // don't return bad results
key: 'normalizado'
}
But there is a weird behaviour after some matches as you can see in the video: https://streamable.com/rq6v6
Weird as it doesn't follow the logical order expected.
What I am trying to do is, try to guess if the searchString matches in the array of names
. It does not matter if it matches any of the names. If it matches I would like to get it's category.
categories json
[
{
"category": "Akshay Kumar",
"names": [
"Akshay Kumar",
"Khiladi",
"Akki"
]
},
{
"category": "Aamir Khan",
"names": [
"Aamir Khan",
"A.K.",
"Mr. Perfectionist",
"Tom Hanks of India"
]
}
]
const fuzzyConfig = {
key: 'names',
allowTypo: true,
limit: 10
};
I am getting below error, not sure if the below stack would be helpful
if (target._targetLowerCodes.length === 0) continue
^
TypeError: Cannot read property 'length' of undefined
at Object.go(/run/media / rinav / workspace / nodeProjects / random / node_modules / fuzzysort / fuzzysort.js: 107: 39)
at / run / media / rinav / workspace / nodeProjects / random / fuzzySort.js: 44: 29
at Object.<anonymous>(/run/media / rinav / workspace / nodeProjects / random / fuzzySort.js: 52: 2)
at Module._compile(module.js: 662: 30)
at Object.Module._extensions..js(module.js: 673: 10)
at Module.load(module.js: 575: 32)
at tryModuleLoad(module.js: 515: 12)
at Function.Module._load(module.js: 507: 3)
at Function.Module.runMain(module.js: 703: 10)
at startup(bootstrap_node.js: 193: 16)
const matches = fuzzysort.go(searchTerm, categories, fuzzyConfig);
Thanks for an awesome library. We've built a neat little feature using fuzzysort which works great in development! However I cannot run a build due to facebook/create-react-app#1125
As Create React App is becoming a pretty popular way to do React projects, I was wondering if it's possible to provide a package to NPM that pre-transpiles to ES5 syntax? I'm happy to contribute a Pull Request if you're not sure how (or don't have time!) to do this.
const wouldSkipAhead = matchesSimple[searchI] > targetI
if(wouldSkipAhead) {
const nextMatchIsNextTarget = matchesSimple[searchI] === targetI
if(!nextMatchIsNextTarget) {
// skip and backfill history
targetI = matchesSimple[searchI]
isConsec = false
const targetCode = target.charCodeAt(targetI-1)
wasUpper = targetCode>=65&&targetCode<=90
wasAlphanum = wasUpper || targetCode>=97&&targetCode<=122 || targetCode>=48&&targetCode<=57
}
}
Is there any situation that nextMatchIsNextTarget
is true
while wouldSkipAhead
is true
?
Please provide a way to change options on an "instance" basis. Users might want to use it in 2 different places with different settings.
Does this thing work well with non-ascii charts? Have the feeling it breaks as soon as one starts adding utf-8 chars like accents or similar chars.
First of, excellent lib.
I wondering if there's a way to search inside a "dictionary" (hope I'm using this word right)?
My structure looks something like this:
list = {
1: { id: 1, attr: 'some value' },
2: { id: 2, attr: 'another value' },
};
Is it possible with this lib?
Are there any plans to convert it to typescript? Want to use this properly in an Angular project.
Should the obj: any
property be present in KeysResults type? https://github.com/farzher/fuzzysort/blob/master/index.d.ts#L38
It extends the KeyResult which has the obj: T
, but in this case it gets overridden with any
You can reproduce it with fuzzysort.single('s', '')
When march an empty search string, the behavior is empty result.
Can add support to alter this behavior? Since the code must distinguish between empty keyword and non-empty keyword, and render result as highlighted or original item text, that add code complexity.
In addition, very good lib, thank you!
I'm performing search on an array which looks like following:
[ { "city" : "Anaa", "country" : "French Polynesia", "code" : "AAA" }, { "city" : "Al Arish", "country" : "Egypt", "code" : "AAC" }, ...]
and so on.
I'm applying a search on 'city' and 'code' fields of the array. So, when the user searches for 'b', he will be shown all results that have b in their 'city' or 'code'.
My question is, how do I give higher priority to results from a particular country? In other words, I want the result to assign higher priority to Indian cities. How can I go about that?
Hi there,
I'm using fuzzysort on an array of objects with the key
object to choose the property of the objects to match against. Some of the objects have the same value in this property, but different values in other properties.
As expected, search terms that match one of these objects also matches the others. My issue is that drilling into the originating object with result.obj
only ever points to one of the original objects, rather than the separate instances.
See example code below (or codepen here):
var targets = [
{name: 'Typography', version: '3.1.0'},
{name: 'Typography', version: '2.1.0'}
]
var results = fuzzysort.go('typography', targets, {key: 'name'})
console.log(results[0].obj.version, results[1].obj.version)
// expected output "3.1.0" and "2.1.0", got output of "3.1.0" and "3.1.0"
First off this is a great library, thank you for all the work you put into this. Works so much faster and is more intuitive than anything else I've tried.
I've noticed that when only searching using a few characters, say 3, it will rank matches higher based on their position in the searched string rather than if the characters are consecutive.
Example:
Search parameter = pin
Search string 1= porting in
Search string 2 = account pin
Result =
I would've expected it to show the reverse
That seems much more relevant to me and maybe there is a way to do this and I just haven't figured it out so any feedback would be appreciated.
As a side note, not sure why porting in would highlight as indicated instead of showing as porting in.
Hi,
Is it possible to make the search go both ways? - When you start with the final word of the search, the algorithm stops: https://streamable.com/r4wd6
You can add some typings:
./index.d.ts
at the root
declare module "fuzzysort" {
interface Result {
score: number;
highlighted: string;
_matchesBest: number[];
_matchesSimple: number[];
_target: string;
_targetLower: string;
}
interface Results {
[index: number]: Result | undefined;
thresholdCount: number;
total: number;
}
const fuzzysort: {
noMatchLimit: number; // If there's no match for a span this long, give up (lower is faster for long search targets)
highlightMatches: boolean; // Turn this off if you don't care about `highlighted` (faster)
highlightOpen: string;
highlightClose: string;
threshold: number | null; // Don't return matches worse than this (lower is faster) (irrelevant for `single`)
limit: number | null; // Don't return more results than this (faster if `highlightMatches` is on) (irrelevant for `single`)
allowTypo: boolean; // Allwos a snigle transpoes in yuor serach (faster when off)
single(search: string, target: string): Result | null;
go(search: string, targets: string[]): Results;
goAsync(search: string, targets: string[]): Promise<Results>;
};
export = fuzzysort;
}
https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html
Not an issue but just want say thank you for this amazing project!
I thought it would be easy to find a fuzzy search lib but after I tried almost all "fuzzy" lib on npm finally find this is the only one that works as expected.
I used it in my project at: http://demo.rekit.org to support Cmd + P to quick open a file. Just for your information.
Thanks again!
Can you add any style guide (maybe with eslint or whatever) so that other people could contribute with style consistency?
Is there a way to make the plugin handle accent as char without accent ? For example in your demo on Steam games, if you enter café
you have the game café society
, but with the search cafe
it doesn't show up.
Is it intended for robust search in files ?
I'm trying to use it as a search in multiples files at once, but I'm getting bad search results. (exact correct word with bad scores (< 20000), multiple instance of word not found, sometimes not found at all )
Is there some option I have to know about ?
(a "multiple results" per key perhaps ?)
Great work, thanks for sharing.
I don't get the highlight function. Are you sure you want to maintain that? Outputing HTML sounds a bit off-topic.
If I were you, I would simply expose matchesBest
and extract the highlighting function to a code sample linked in the readme.
You've thought about the case sensitiveness, but what about diacritics? With double chars diacritics, it can get complicated quickly.
You can let the user prepare the data and the searched value (toLowerCase/Diacritics) and simply output matches (do the thing you do best).
Hi,
This is not an issue. I just want to thank you @farzher for your amazing library. I just released a search library for Ghost Blogging Platform called ghost-search
and it's using fuzzysort
as a search algorithm.
After a testing multiple libraries like lunr
, fuse
, and other search libraries, fuzzysort
seems to be the one that does the job properly. When I started I was not expecting that finding a search library would be so hard. Boy I was wrong.
Thank you again and keep up the good work.
As far as I can see, there is no possibility to highlight the data, when using .go with an array of targets.
My use case:
let search = 'abl';
let data = [{ label: "Label A", value: 1},{ label: "Label B", value: 2}];
let sorted = fuzzysort.go(search, data, {
keys: ['label']
}).map(d => d.obj); // convert back to the original data array
Now i want to highlight the data, in the sorted
variable.
[{ label: "L<b>ab</b>e<b>l</b> A", value: 1},{ label: "L<b>ab</b>e<b>l</b> B", value: 2}]
My suggestion is to extend the options
object, with a highlight property. So it will still be performant enough.
Hey! Thanks for all the hard work, I love the lib! So efficient!
I found a bug in the lib where only the first ocurence is taken into account to generate indexes:
Example:
const results = fuzzysort.go('mr', ['Mr something mr']);
=> res.indexes = [0,1] // Should be [0,1,13,14]
Let me know if I can help.
Please move to a UMD shim instead of custom isNode flag.
You may want to use CommonJS through Webpack/Other linkers.
This is a list of changes I'm considering for v1.0, feel free to give feedback/suggestions
fuzzysort.highlight(result)
fuzzysort.limit = 1
to fuzzysort.go(search, targets, {limit: 1})
key
or keys
:fuzzysort.go(search, objects, {key: 'title'})
fuzzysort.go(search, objects, {
keys: ['title', 'desc'],
scoreFn: (a) => Math.max(a[0]?a[0].score:-Infinity, a[1]?a[1].score-100:-Infinity) // optional
})
Is there a changelog for 1.1.2 / 3 / 4?
When creating an instance with default options, the library doesn't make use of the key
or keys
options.
Example
const fz = fuzzysort.new({
key: 'someKey',
// other options
});
fz.go('a', [{ someKey: 'a' }, { someKey: 'b' }]); // error
fz.go('a', [{ someKey: 'a' }, { someKey: 'b' }], { key: 'someKey' }); // works
I have an array like this:
[ { value: '2MoisDePréavis',
count: '1',
label: '2 mois de préavis' },
{ value: 'AbandonDePoste',
count: '1',
label: 'Abandon de poste' },
{ value: 'Abandonnait', count: '1', showAs: 'Abandonnait' },
{ value: 'AbusiveDeContrat',
count: '1',
label: 'Abusive de contrat' },
{ value: 'AbusiveDuContrat',
count: '1',
label: 'Abusive du contrat' } ]
When i run the fuzzysort, the result object in the promise always has the obj value returned as null
fuzzysort.goAsync("Aba", arr, {keys: ['label']}).then(.....)
In fuzzysort goAsync the obj value is not null when set ( i console logged it ) .
I am running this on the server side (Node JS 8.9)
Hi, While testing on Internet Explorer 11 the following error appears in the console:
Object doesn't support property or method 'assign'
Line 549 in b77b533
Hi, I am trying this search
const fuzzysortOptions = {
limit: 50, // don't return more results than you need!
allowTypo: false, // if you don't care about allowing typos
threshold: -10000, // don't return bad results
keys: ["username"]
}
fuzzysort.go(
'ssa',
[
{ code: 'USR-20181206042453262-0QqTbZRi', username: 'ssampson0' },
{ code: 'USR-20181206042453311-GhgVv1j7', username: 'rfitzer1' }
],
fuzzysortOptions
)
And getting this result
[ [ { "target": "ssampson0", "_targetLowerCodes": [ 115, 115, 97, 109, 112, 115, 111, 110, 48 ], "_nextBeginningIndexes": [ 9, 9, 9, 9, 9, 9, 9, 9, 9 ], "score": -6, "indexes": [ 0, 1, 2 ], "obj": null } ] ]
However, obj is always null.
If you find this is not an issue, Can you advice to locate the items in the targets arrays?
Hi, thanks for the time you spend on making this great library available to the public.
I'm indexing 100k objects. I really only want to search on obj.title. I'm only indexing objects so that I can also get obj.id back and do things with it. When I try to prepare objects:
this._targets = records.map(record => fuzzysort.prepare(record));
An example record:
{ _id: '09vlkj23029',
_rev: '5-25acb1dd8a674d62bd39367dec7a3a9d',
domain: 'mysite.com',
source: 'myConnector',
title: 'Jones Company - My Site',
url: 'https://mysite.com/09vlkj23029' }
I get TypeError: str.toLowerCase is not a function
, and I believe it's due to this line assuming targets are strings: https://github.com/farzher/fuzzysort/blob/master/fuzzysort.js#L511
It looks like a way to prepare an object could be built, but isn't yet implemented. Or maybe it was a regression. Any thoughts on this? Thanks again.
Hi.
I recently started using this library, but got an error with if(target === undefined) continue
since it did not match null values.
I was planning on making a PR, but noticed in the 1.0.5 release on github this has actually been fixed and replaced by if(!target)
.
However, I use 1.0.5 fetched from NPM, and the source code i got from there uses triple equals undefined!
Hi there! Does anyone have an idea why my scoreFn doesn't work? Thanks all!
let options = {
limit: 100,
allowTypo: false,
threshold: -10000,
keys: ["name1","name2"],
scoreFn: function(a) {console.log(JSON.stringify(a,null,2)); return a[0].score;} //function seems to be broken -- scoreFn input always receives [null,null]
};
let results = fuzzysort.go("a", [{"name1":"ab","name2":"k"},{"name1":"b","name2":"k"}], options);
Currently FuzzySort doesn't specify which license it is released under.
Please move to ES5 syntax
=>
functionsconst
for ... of
Usual webpack setups do not compile down node_module dependencies to es5.
It will make UglifyJS choke and won't work on some browsers.
If you want, you can provide both es6 and es5 through a package.json flag.
It's pretty cool that you made a much faster, NPM version of this. It'd be nice if you could at least point people towards my original blog post.
https://blog.forrestthewoods.com/reverse-engineering-sublime-text-s-fuzzy-match-4cffeed33fdb
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.