Skip to content

Commit

Permalink
feat(items): add support for arrays (#7)
Browse files Browse the repository at this point in the history
With this commit you can now specify an array of items to rank and those
items will be checked individually (before, they were joined with a
comma via toString, which is sub optimal).
  • Loading branch information
Kent C. Dodds authored and conorhastings committed Aug 29, 2016
1 parent 17d5e59 commit 2233ff4
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,15 @@ const objList = [
matchSorter(objList, 'g', {keys: ['name', 'color']}) // [{name: 'George', color: 'Blue'}, {name: 'Janice', color: 'Green'}]
matchSorter(objList, 're', {keys: ['color', 'name']}) // [{name: 'Jen', color: 'Red'}, {name: 'Janice', color: 'Green'}, {name: 'Fred', color: 'Orange'}]

//this also works with **nested keys**
// You can specify a key that is an array of values and the best match from that value is the one that's used for the ranking
const iceCreamYum = [
{favoriteIceCream: ['mint', 'chocolate']},
{favoriteIceCream: ['candy cane', 'brownie']},
{favoriteIceCream: ['birthday cake', 'rocky road', 'strawberry']},
]
matchSorter(iceCreamYum, 'cc', {keys: 'favoriteIceCream'}) // [{favoriteIceCream: ['candy cane', 'brownie']}, {favoriteIceCream: ['mint', 'chocolate']}]

// this also works with **nested keys**
const nestedObjList = [
{name: {first: 'Janice'}},
{name: {first: 'Fred'}},
Expand Down
14 changes: 12 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ function getHighestRanking(item, keys, value) {
if (!keys) {
return {rank: getMatchRanking(item, value), keyIndex: -1}
}
return keys.reduce(({rank, keyIndex}, key, i) => {
const itemValue = getItemValue(item, key)
const valuesToRank = getAllValuesToRank(item, keys)
return valuesToRank.reduce(({rank, keyIndex}, itemValue, i) => {
const newRank = getMatchRanking(itemValue, value)
if (newRank > rank) {
rank = newRank
Expand Down Expand Up @@ -186,4 +186,14 @@ function getItemValue(item, key) {
return key.split('.').reduce((itemObj, nestedKey) => itemObj[nestedKey], item)
}

/**
* Gets all the values for the given keys in the given item and returns an array of those values
* @param {Object} item - the item from which the values will be retrieved
* @param {Array} keys - the keys to use to retrieve the values
* @return {Array} the values in an array
*/
function getAllValuesToRank(item, keys) {
return keys.reduce((allVals, key) => allVals.concat(getItemValue(item, key)), [])
}

module.exports = exports.default // CommonJS compat
29 changes: 29 additions & 0 deletions src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,35 @@ const tests = {
{name: {first: 'bat'}},
],
},
'can handle keys that are an array of values': {
input: [
[
{favoriteIceCream: ['mint', 'chocolate']},
{favoriteIceCream: ['candy cane', 'brownie']},
{favoriteIceCream: ['birthday cake', 'rocky road', 'strawberry']},
],
'cc',
{keys: ['favoriteIceCream']},
],
output: [
{favoriteIceCream: ['candy cane', 'brownie']},
{favoriteIceCream: ['mint', 'chocolate']},
],
},
'when using arrays of values, when things are equal, the one with the higher index wins': {
input: [
[
{favoriteIceCream: ['mint', 'chocolate']},
{favoriteIceCream: ['chocolate', 'brownie']},
],
'chocolate',
{keys: ['favoriteIceCream']},
],
output: [
{favoriteIceCream: ['chocolate', 'brownie']},
{favoriteIceCream: ['mint', 'chocolate']},
],
},
'when providing a rank threshold of NO_MATCH, it returns all of the items': {
input: [
['orange', 'apple', 'grape', 'banana'],
Expand Down

0 comments on commit 2233ff4

Please sign in to comment.