Skip to content

add typescript definitions, update readme #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
index.cjs.js
node_modules/
index.d.ts
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ npm i --save fzy.js
`score(needle, haystack)`

``` javascript
var fzy = require('fzy.js')
var fzy = require('fzy.js') // CJS

// import * as fzy from "fzy.js" // ESM

fzy.score("amuser", "app/models/user.rb") // 5.595
fzy.score("amuser", "app/models/customer.rb") // 3.655
Expand All @@ -41,8 +43,9 @@ See the full example below for a way to do this check.
# Full Example

``` javascript
var { sortBy, escapeRegExp } = require("lodash");
var fzy = require("fzy.js");
var fzy = require('fzy.js') // CJS

// import * as fzy from "fzy.js" // ESM

// List of candidate strings
// Often generated by something like require("glob")("**/*")
Expand All @@ -56,10 +59,10 @@ var list = [
var query = "amuser";

// fzy.js includes `hasMatch` which can be used for filtering
list = list.filter((s) => fzy.hasMatch(s));
list = list.filter((s) => fzy.hasMatch(query, s));

// Sort by fzy's scoring, descending (higher scores are better matches)
list = sortBy(list, (s) => -fzy.score(query, s));
list = list.sort((a,b) => fzy.score(query, b) - fzy.score(query, a));

// Select only the first 10 results
list.slice(0, 10);
Expand All @@ -84,5 +87,5 @@ list.forEach((s) => {
//
// app/models/customer.rb
// a m us er

```

38 changes: 36 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-check
var SCORE_MIN = -Infinity;
var SCORE_MAX = Infinity;

Expand All @@ -10,14 +11,23 @@ var SCORE_MATCH_WORD = 0.8
var SCORE_MATCH_CAPITAL = 0.7
var SCORE_MATCH_DOT = 0.6

/**
* @param {string} s
*/
function islower(s) {
return s.toLowerCase() === s;
}

/**
* @param {string} s
*/
function isupper(s) {
return s.toUpperCase() === s;
}

/**
* @param {string} haystack
*/
function precompute_bonus(haystack) {
/* Which positions are beginning of words */
var m = haystack.length;
Expand Down Expand Up @@ -45,14 +55,20 @@ function precompute_bonus(haystack) {
return match_bonus;
}

/**
* @param {string} needle
* @param {string} haystack
* @param {number[][]} D
* @param {number[][]} M
*/
function compute(needle, haystack, D, M) {
var n = needle.length;
var m = haystack.length;

var lower_needle = needle.toLowerCase();
var lower_haystack = haystack.toLowerCase();

var match_bonus = precompute_bonus(haystack, match_bonus);
var match_bonus = precompute_bonus(haystack);

/*
* D[][] Stores the best score for this position ending with a match.
Expand Down Expand Up @@ -88,6 +104,11 @@ function compute(needle, haystack, D, M) {
}
}

/**
* @param {string} needle
* @param {string} haystack
* @returns {number}
*/
function score(needle, haystack) {
var n = needle.length;
var m = haystack.length;
Expand Down Expand Up @@ -120,6 +141,11 @@ function score(needle, haystack) {
return M[n - 1][m - 1];
}

/**
* @param {string} needle
* @param {string} haystack
* @returns {number[]}
*/
function positions(needle, haystack) {
var n = needle.length;
var m = haystack.length;
Expand All @@ -144,7 +170,10 @@ function positions(needle, haystack) {

compute(needle, haystack, D, M)

/* backtrack to find the positions of optimal matching */
/**
* backtrack to find the positions of optimal matching
* @type {number | boolean}
*/
var match_required = false;

for (var i = n - 1, j = m - 1; i >= 0; i--) {
Expand Down Expand Up @@ -175,6 +204,11 @@ function positions(needle, haystack) {
return positions;
}

/**
* @param {string} needle
* @param {string} haystack
* @returns {boolean}
*/
function hasMatch(needle, haystack) {
needle = needle.toLowerCase()
haystack = haystack.toLowerCase()
Expand Down
Loading