diff --git a/.all-contributorsrc b/.all-contributorsrc
index ef0770e..2404b0b 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -104,6 +104,17 @@
"contributions": [
"code"
]
+ },
+ {
+ "login": "tikotzky",
+ "name": "Mordy Tikotzky",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/200528?v=4",
+ "profile": "https://github.com/tikotzky",
+ "contributions": [
+ "code",
+ "doc",
+ "test"
+ ]
}
],
"repoType": "github"
diff --git a/README.md b/README.md
index 5af62d4..070c80a 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
[![downloads][downloads-badge]][npm-stat]
[![MIT License][license-badge]][license]
-[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors)
+[![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors)
[![PRs Welcome][prs-badge]][prs]
[![Donate][donate-badge]][donate]
[![Code of Conduct][coc-badge]][coc]
@@ -54,21 +54,20 @@ To explain the ranking system, I'll use countries as an example:
This ranking seems to make sense in people's minds. At least it does in mine. Feedback welcome!
-
-* [Getting Started](#getting-started)
- * [Installation](#installation)
- * [Usage](#usage)
-* [Advanced options](#advanced-options)
- * [keys: `[string]`](#keys-string)
- * [threshold: `number`](#threshold-number)
- * [keepDiacritics: `boolean`](#keepdiacritics-boolean)
-* [Using ES6?](#using-es6)
-* [Inspiration](#inspiration)
-* [Other Solutions](#other-solutions)
-* [Contributors](#contributors)
-* [LICENSE](#license)
+- [Getting Started](#getting-started)
+ - [Installation](#installation)
+ - [Usage](#usage)
+- [Advanced options](#advanced-options)
+ - [keys: `[string]`](#keys-string)
+ - [threshold: `number`](#threshold-number)
+ - [keepDiacritics: `boolean`](#keepdiacritics-boolean)
+- [Using ES6?](#using-es6)
+- [Inspiration](#inspiration)
+- [Other Solutions](#other-solutions)
+- [Contributors](#contributors)
+- [LICENSE](#license)
@@ -160,6 +159,16 @@ matchSorter(list, 'j', {keys: [item => item.name]})
// [{name: 'Janice'}, {name: 'Jen'}]
```
+**Threshold**: You may specify an individual threshold for specific keys. A key will only match if it meets the specified threshold. _For more information regarding thresholds [see below](#threshold-number)_
+
+```javascript
+const list = [{name: 'Fred', color: 'Orange'}, {name: 'Jen', color: 'Red'}]
+matchSorter(list, 'ed', {
+ keys: [{threshold: rankings.STARTS_WITH, key: 'name'}, 'color'],
+})
+//[{name: 'Jen', color: 'Red'}]
+```
+
**Min and Max Ranking**: You may restrict specific keys to a minimum or maximum ranking by passing in an object. A key with a minimum rank will only get promoted if there is at least a simple match.
```javascript
@@ -198,16 +207,16 @@ _Default: `MATCHES`_
Thresholds can be used to specify the criteria used to rank the results.
Available thresholds (from top to bottom) are:
-* CASE_SENSITIVE_EQUAL
-* EQUAL
-* STARTS_WITH
-* WORD_STARTS_WITH
-* STRING_CASE
-* STRING_CASE_ACRONYM
-* CONTAINS
-* ACRONYM
-* MATCHES _(default value)_
-* NO_MATCH
+- CASE_SENSITIVE_EQUAL
+- EQUAL
+- STARTS_WITH
+- WORD_STARTS_WITH
+- STRING_CASE
+- STRING_CASE_ACRONYM
+- CONTAINS
+- ACRONYM
+- MATCHES _(default value)_
+- NO_MATCH
```javascript
const fruit = ['orange', 'apple', 'grape', 'banana']
@@ -269,11 +278,10 @@ You might try [Fuse.js](https://github.com/krisk/Fuse). It uses advanced math fa
Thanks goes to these people ([emoji key][emojis]):
-
| [
Kent C. Dodds](https://kentcdodds.com)
[π»](https://github.com/kentcdodds/match-sorter/commits?author=kentcdodds "Code") [π](https://github.com/kentcdodds/match-sorter/commits?author=kentcdodds "Documentation") [π](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [β οΈ](https://github.com/kentcdodds/match-sorter/commits?author=kentcdodds "Tests") [π](#review-kentcdodds "Reviewed Pull Requests") | [
Conor Hastings](http://conorhastings.com)
[π»](https://github.com/kentcdodds/match-sorter/commits?author=conorhastings "Code") [π](https://github.com/kentcdodds/match-sorter/commits?author=conorhastings "Documentation") [β οΈ](https://github.com/kentcdodds/match-sorter/commits?author=conorhastings "Tests") [π](#review-conorhastings "Reviewed Pull Requests") | [
Rogelio Guzman](https://github.com/rogeliog)
[π](https://github.com/kentcdodds/match-sorter/commits?author=rogeliog "Documentation") | [
ClaudΓ©ric Demers](http://ced.io)
[π»](https://github.com/kentcdodds/match-sorter/commits?author=clauderic "Code") [π](https://github.com/kentcdodds/match-sorter/commits?author=clauderic "Documentation") [β οΈ](https://github.com/kentcdodds/match-sorter/commits?author=clauderic "Tests") | [
Kevin Davis](kevindav.us)
[π»](https://github.com/kentcdodds/match-sorter/commits?author=osfan501 "Code") [β οΈ](https://github.com/kentcdodds/match-sorter/commits?author=osfan501 "Tests") | [
Denver Chen](https://github.com/nfdjps)
[π»](https://github.com/kentcdodds/match-sorter/commits?author=nfdjps "Code") [π](https://github.com/kentcdodds/match-sorter/commits?author=nfdjps "Documentation") [β οΈ](https://github.com/kentcdodds/match-sorter/commits?author=nfdjps "Tests") | [
Christian Ruigrok](http://ruigrok.info)
[π](https://github.com/kentcdodds/match-sorter/issues?q=author%3AChrisRu "Bug reports") [π»](https://github.com/kentcdodds/match-sorter/commits?author=ChrisRu "Code") [π](https://github.com/kentcdodds/match-sorter/commits?author=ChrisRu "Documentation") |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
-| [
Hozefa](https://github.com/hozefaj)
[π](https://github.com/kentcdodds/match-sorter/issues?q=author%3Ahozefaj "Bug reports") [π»](https://github.com/kentcdodds/match-sorter/commits?author=hozefaj "Code") [β οΈ](https://github.com/kentcdodds/match-sorter/commits?author=hozefaj "Tests") [π€](#ideas-hozefaj "Ideas, Planning, & Feedback") | [
pushpinder107](https://github.com/pushpinder107)
[π»](https://github.com/kentcdodds/match-sorter/commits?author=pushpinder107 "Code") |
+| [
Hozefa](https://github.com/hozefaj)
[π](https://github.com/kentcdodds/match-sorter/issues?q=author%3Ahozefaj "Bug reports") [π»](https://github.com/kentcdodds/match-sorter/commits?author=hozefaj "Code") [β οΈ](https://github.com/kentcdodds/match-sorter/commits?author=hozefaj "Tests") [π€](#ideas-hozefaj "Ideas, Planning, & Feedback") | [
pushpinder107](https://github.com/pushpinder107)
[π»](https://github.com/kentcdodds/match-sorter/commits?author=pushpinder107 "Code") | [
Mordy Tikotzky](https://github.com/tikotzky)
[π»](https://github.com/kentcdodds/match-sorter/commits?author=tikotzky "Code") [π](https://github.com/kentcdodds/match-sorter/commits?author=tikotzky "Documentation") [β οΈ](https://github.com/kentcdodds/match-sorter/commits?author=tikotzky "Tests") |
diff --git a/src/__tests__/index.js b/src/__tests__/index.js
index ba4ee0f..28d7aa0 100644
--- a/src/__tests__/index.js
+++ b/src/__tests__/index.js
@@ -373,6 +373,27 @@ const tests = {
{tea: 'Green', alias: 'C'},
],
},
+ 'only match when key meets threshold': {
+ input: [
+ [{name: 'Fred', color: 'Orange'}, {name: 'Jen', color: 'Red'}],
+ 'ed',
+ {
+ keys: [{threshold: rankings.STARTS_WITH, key: 'name'}, 'color'],
+ },
+ ],
+ output: [{name: 'Jen', color: 'Red'}],
+ },
+ 'should match when key threshold is lower than the default threshold': {
+ input: [
+ [{name: 'Fred', color: 'Orange'}, {name: 'Jen', color: 'Red'}],
+ 'ed',
+ {
+ keys: ['name', {threshold: rankings.CONTAINS, key: 'color'}],
+ threshold: rankings.STARTS_WITH,
+ },
+ ],
+ output: [{name: 'Jen', color: 'Red'}],
+ },
}
Object.keys(tests).forEach(title => {
diff --git a/src/index.js b/src/index.js
index a2e1ac4..ebf1e60 100644
--- a/src/index.js
+++ b/src/index.js
@@ -46,8 +46,13 @@ function matchSorter(items, value, options = {}) {
return matchedItems.sort(sortRankedItems).map(({item}) => item)
function reduceItemsToRanked(matches, item, index) {
- const {rank, keyIndex} = getHighestRanking(item, keys, value, options)
- if (rank >= threshold) {
+ const {rank, keyIndex, keyThreshold = threshold} = getHighestRanking(
+ item,
+ keys,
+ value,
+ options,
+ )
+ if (rank >= keyThreshold) {
matches.push({item, rank, index, keyIndex})
}
return matches
@@ -60,17 +65,21 @@ function matchSorter(items, value, options = {}) {
* @param {Array} keys - the keys to get values from the item for the ranking
* @param {String} value - the value to rank against
* @param {Object} options - options to control the ranking
- * @return {{rank: Number, keyIndex: Number}} - the highest ranking
+ * @return {{rank: Number, keyIndex: Number, keyThreshold: Number}} - the highest ranking
*/
function getHighestRanking(item, keys, value, options) {
if (!keys) {
- return {rank: getMatchRanking(item, value, options), keyIndex: -1}
+ return {
+ rank: getMatchRanking(item, value, options),
+ keyIndex: -1,
+ keyThreshold: options.threshold,
+ }
}
const valuesToRank = getAllValuesToRank(item, keys)
return valuesToRank.reduce(
- ({rank, keyIndex}, {itemValue, attributes}, i) => {
+ ({rank, keyIndex, keyThreshold}, {itemValue, attributes}, i) => {
let newRank = getMatchRanking(itemValue, value, options)
- const {minRanking, maxRanking} = attributes
+ const {minRanking, maxRanking, threshold} = attributes
if (newRank < minRanking && newRank >= rankings.MATCHES) {
newRank = minRanking
} else if (newRank > maxRanking) {
@@ -79,10 +88,11 @@ function getHighestRanking(item, keys, value, options) {
if (newRank > rank) {
rank = newRank
keyIndex = i
+ keyThreshold = threshold
}
- return {rank, keyIndex}
+ return {rank, keyIndex, keyThreshold}
},
- {rank: rankings.NO_MATCH, keyIndex: -1},
+ {rank: rankings.NO_MATCH, keyIndex: -1, keyThreshold: options.threshold},
)
}