Git Product home page Git Product logo

fuzzysort's People

Contributors

farzher avatar imhoffd avatar krinkle avatar kyuwoo-choi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fuzzysort's Issues

Getting setImmediate error in Create React App

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!

Result object is memory hungry (in place sorting?)

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

Indices of search results needed

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.

How to get the score between 0.0 and 1.0

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

Any option / method for whole string matching only

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.

Support for searching over objects with multiple keys (targets)

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

Feat discussion

hi, i want add additional usage about fuzzysort.highlight . Some time we want wrapper different style for the matches.
Eg:
t and test => <red>t</red>es<blue>t</bule>
so , and new feat look like

code

If i miss something , point me out is appreciate !
And thx this wonderful lib

How do i return results where the order is change

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

Add a option for Latin extended characters map

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

Odd sort order

screen shot 2018-04-23 at 10 20 54 am

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.

Are there some sort limits?

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.

How to perform fuzzySort if the key is an Array of Strings?

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);

Compatibility with Create React App

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.

useless condition

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?

Options behavior

Please provide a way to change options on an "instance" basis. Users might want to use it in 2 different places with different settings.

Non-ascii chars?

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.

Search in dictionary

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?

Plans to convert to TS?

Are there any plans to convert it to typescript? Want to use this properly in an Angular project.

Empty string match behavior

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!

How to give higher priority to certain entries over others?

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?

Duplicate results

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"

Rank consecutive characters higher regardless of position in string

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 =

  1. porting in
  2. account pin

I would've expected it to show the reverse

  1. account pin
  2. porting in

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.

Typescript

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

Thanks for this great library!

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!

Suggestion for a style guide

Can you add any style guide (maybe with eslint or whatever) so that other people could contribute with style consistency?

Accents

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.

Search in files

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.

Highlighting API

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).

Thank you for your library

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.

how to highlight when using fuzzysort.go() with array of targets?

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.

Highlighting indexes are generated only for the first match

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.

UMD Shim

Please move to a UMD shim instead of custom isNode flag.
You may want to use CommonJS through Webpack/Other linkers.

v1.0 changes feedback/suggestions

This is a list of changes I'm considering for v1.0, feel free to give feedback/suggestions

  1. Invert the score to be negative, so that higher scores are better.
  2. Remove the option to automatically highlight and expose fuzzysort.highlight(result)
  3. Move options from fuzzysort.limit = 1 to fuzzysort.go(search, targets, {limit: 1})
  4. Add ability to search objects by 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
})

Options "key" and "keys" are not taken from instanceOptions

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

obj property is always null

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)

Support for ancient browsers

Hi, While testing on Internet Explorer 11 the following error appears in the console:

Object doesn't support property or method 'assign'

var fastpriorityqueue = function(){function t(){function t(){for(var t=0,a=r[t],s=1;s<i;){var o=s+1;t=s,o<i&&r[o].score<r[s].score&&(t=o),r[t-1>>1]=r[t],s=1+(t<<1)}for(var n=t-1>>1;t>0&&a.score<r[n].score;t=n,n=t-1>>1)r[t]=r[n];r[t]=a}var r=[],i=0,a=Object.assign({});return a.add=function(t){var a=i;r[i++]=t;for(var s=a-1>>1;a>0&&t.score<r[s].score;a=s,s=a-1>>1)r[a]=r[s];r[a]=t},a.poll=function(){var a=r[0];return r[0]=r[--i],t(),a},a.peek=function(t){return r[0]},a.replaceTop=function(i){r[0]=i,t()},a}return t}()

obj property is always null

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?

Preparing objects for performance improvement

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.

1.0.5 on npm is not the same as 1.0.5 on github

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!

scoreFn always receives [null,null] as an input?

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);

Move to ES5

Please move to ES5 syntax

  • replace arrow => functions
  • replace const
  • replace for ... of
  • replace string ` backticks

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.